Error while accessing javascript array element inspite of having checks - javascript

I am doing following in my javascript code
if(
typeof player['stats'] != undefined &&
typeof player['stats']['guild'] != undefined &&
typeof player['stats']['guild']['master'] != undefined &&
typeof player['stats']['guild']['master']['since'] != undefined
)
However I get error:
Cannot read property 'since' of null
I have been stuck with this for a while. Can any javascript gurus help me please?

typeof returns string, so compare against "undefined"
if(
typeof player['stats'] != "undefined" &&
typeof player['stats']['guild'] != "undefined" &&
typeof player['stats']['guild']['master'] != "undefined" &&
player['stats']['guild']['master'] != null &&
typeof player['stats']['guild']['master']['since'] != "undefined"
)

Just check if the value is truthy:
if(
player['stats'] &&
player['stats']['guild'] &&
player['stats']['guild']['master'] &&
player['stats']['guild']['master']['since'] != undefined // only check the last one as it is probably not an object but another value such as 0 (depending on what your data looks like, if you have it as an object then just remove the != undefined check)
)

You could write a fairly simple object getter function which you pass the object and then a dot-delimited key to find a value like so:
function getObj(obj, key) {
return key.split(".").reduce((acc, cur) => {
if (acc !== undefined) {
return acc[cur];
}
return acc;
}, obj);
}
Then, you can grab the value that you want and see if it's undefined or not:
const player = {
stats: {
guild: {
master: {
since: '2004'
}
}
}
};
const since = getObj(player, 'stats.guild.master.since');
if (since) {
// do some code
}
This is a handy utility function you can use on any object and makes your if statement much prettier.

You can also avoid the multiple lookups with a temporary variable:
player = { stats: { guild: { master: null } } }
if ((temp = player.stats) &&
(temp = temp.guild) &&
(temp = temp.master) &&
(temp = temp.since) !== undefined)
console.log(true , temp)
else
console.log(false, temp)
player.stats.guild.master = { since: 'today' }
if ((temp = player.stats) &&
(temp = temp.guild) &&
(temp = temp.master) &&
(temp = temp.since) !== undefined)
console.log(true , temp)
else
console.log(false, temp)

Related

How do I check the type of a variable inside an `if` statement

There is a problem in this area
if (components[i] == **TextOptionType**) {
I'm self-debugging a plug-in for a program called obsidian.
~ObsidianDevLibrary.ts is located at Importing ~type.ts.
There is a problem in referring to TextOptionType as a value.
How can I solve this?
type.ts
export type TextOptionType = {
[propName: string] : any,
key: string,
placeholder?: string,
autoSave?: boolean,
value?: boolean,
onChange?: onChangeType,
}
ObsidianDevLibrary.ts
for (let i = 0; i < components.length; i++) {
if (components[i] == TextOptionType) {
componentsToReturn.push(this.addText(setting, components[i]))
}
}
Maybe comparing TextOptionType with if is wrong grammar, but I don't know the right way.
It may be intended to verify that the data entering the component is formatted
https://github.com/KjellConnelly/obsidian-dev-tools
Define a type-predicate function that checks for known members of TextOptionType, like so:
function isTextOptionType( x: unknown ): x is TextOptionType {
const whatIf = x as TextOptionType;
return (
( typeof whatIf === 'object' && whatIf !== null )
&&
( typeof whatIf.key === 'string' )
&&
( typeof whatIf.placeholder === 'string' || typeof whatIf.placeholder === 'undefined' )
&&
( typeof whatIf.autoSave === 'boolean' || typeof whatIf.autoSave === 'undefined' )
&&
( typeof whatIf.value === 'boolean' || typeof whatIf.value === 'undefined' )
&&
( typeof whatIf.onChange === 'function' || typeof whatIf.onChange === 'undefined' )
);
}
Used like so:
for( const c of components ) {
if( isTextOptionType( c ) ) {
componentsToReturn.push( this.addText( setting, c ) );
}
}

Javascript Empty String vs (null and undefined) [duplicate]

This question already has answers here:
How can I check for "undefined" in JavaScript? [duplicate]
(16 answers)
Closed 6 years ago.
I have a object
var data = {1:undefined,2:null,3:10,4:""}
I want to replace all the undefined and null values by 0. I am using the following code to do that:
for (var index in data) {
if (!data[index]) {
data[index] = 0;
}
}
Result I am expecting is : {1:0,2:0,3:10:4:""}
But Result is : {1:0,2:0,3:10:4:0} because it is considering empty string as null. Is it known behavior ?
I can check it by using
(if(data[index] == undefined || data[index] == null))
But I wanted to know the behavior of the above solution.
You can add typeof data[index] != 'string'
var data = {1:undefined,2:null,3:10,4:""}
for (var index in data) {
if (!data[index] && typeof data[index] != 'string') {
data[index] = 0;
}
}
console.log(data)
This is because a string of length 0 is "falsy", which means that it, if evaluated as a boolean, will translate to false. Read more on "falsy" over here. You can fix your code in the following way:
for (var index in data) {
if (typeof data[index] == "undefined" || data[index] == null) {
data[index] = 0;
}
}
Try:
if ((typeof <your variable> == "undefined") ||
( <your variable> == "" ) ) {
<your variable> = 0 ;
}
By the way, Are you using "1", "2" indices?

Is the syntax of this IF/OR statement wrong?

What is wrong with this code?
var variable = prompt("Choose answer1, answer2, answer3 or answer4");
if ((variable !== "answer1") || (variable !== "answer2") || (variable !== "answer3") || (variable !== "answer4")) {
return "You must choose one of these four options!"
}
Your current solution will be always true because variable will not allways be all answers at the same time.
You could use == instead of !== and then negate the whole expression:
if (!((variable == "answer1") || (variable == "answer2") || (variable == "answer3") || (variable == "answer4"))) {
or use and instead of or
if ((variable !== "answer1") && (variable !== "answer2") && (variable !== "answer3") && (variable !== "answer4")) {
in both cases the expression will be true if it is not any of the answers and false if it is one answer.

How can I loop through two arrays comparing values in Javascript?

I have the following Javascript function where the parameters newValue and oldValue are arrays of integers and the same length. Any values in these arrays can be an integer, undefined or null:
function (newValue, oldValue) {
});
Is there some way that I could check the values in the arrays one element at a time and then do an action only if:
newValue[index] is >= 0 and < 999
oldValue[index] is >= 0 and < 999
newValue[index] is not equal to oldValue[index]
What I am not sure of is how can I handle in my checks and ignore the cases where newValue or oldValue are not null and not undefined? I know I can do a check as in if (newValue) but then this will show false when it's a 0.
Update:
I had a few quick answers so far but none are checking the right things which I listed above.
compare against null and undefined:
if (newValue[index] !== null && typeof newValue[index] !== 'undefined') {}
for OPs update:
n = newValue[index];
o = oldValue[index];
if (
n !== null && typeof n !== 'undefined' && n >= 0 && n < 999 &&
o !== null && typeof o !== 'undefined' && o >= 0 && o < 999
) {
// your code
}
for array-elements its not necessary to use typeof so n !== undefined is ok because the variable will exist.
n = newValue[index];
o = oldValue[index];
if (
n !== null && n !== undefined && n >= 0 && n < 999 &&
o !== null && o !== undefined && o >= 0 && o < 999 &&
n !== o
) {
// your code
}
This will do it:
function isEqual (newValue, oldValue) {
for (var i=0, l=newValue.length; i<l; i++) {
if (newValue[i] == null || newValue[i] < 0 || newValue[i] >= 999
|| oldValue[i] == null || oldValue[i] < 0 || oldValue[i] >= 999)
continue;
if (newVale[i] !== oldValue[i])
return false;
}
return true;
}
if (newValue != null || newValue != undefined) && (oldValue != null || oldValue != undefined)

Strange clause in Javascript the Good Parts

This code is from the section of recursion.
var getElementsByAttribute = function (att, value) {
var results = [];
walk_the_DOM(document.body, function (node) {
var actual = node.nodeType === 1 && node.getAttribute(att);
if (typeof actual === 'string' &&
(actual === value || typeof value !== 'string')) {
results.push(node);
}
});
return results;
};
I don't understand the point of the clause below:
typeof actual === 'string' && (actual === value || typeof value !== 'string')
How is it different from?
typeof actual === 'string' && actual === value
typeof actual === 'string' && (actual === value || typeof value !== 'string')
This will return true if and only if actual is a string, and either actual === value, or value is not a string.
typeof actual === 'string' && actual === value
This will return true if and only if actual is a string and either actual === value.
In other words, the first condition returns true if value is anything other than a string, whereas the second condition will only return true if it is a string, and strictly equal to actual.

Categories