Javascript: check for key in array that might not exist - javascript

Say boundEvents is an array that might or might not exist. If it doesn't exist, then the following code will return 'undefined':
console.log(typeof boundEvents);
Fine. That is exactly what I want. Now say I want to check that theoretical array for the existence of a key which might or might not exist.
console.log(typeof boundEvents['click']);
Uh oh:
Uncaught TypeError: Cannot read property 'click' of undefined
Fair enough, javascript. So let's check to see if the array exists, before we check for the key:
if(typeof boundEvents != 'undefined'){
console.log(typeof boundEvents['click']);
}
Working again, but I'm wondering if there is a way to eliminate the if statement and just check on the existence of boundEvents['click'] directly, in one step?
Thanks!
EDIT: complete answer, combined from below:
var boundEvents = boundEvents || {};
console.log(boundEvents.hasOwnProperty('click'));

You can do:
boundEvents = boundEvents || {};
console.log(boundEvents['click']);
or in a single line:
console.log((boundEvents || {})['click']);

If you want an explicit true / false then:
(boundEvents || {}).hasOwnProperty('click')

You can check each layer ending on the variable you want. This will default to undefined if everything is false.
( (typeof boundEvents !== "undefined") && boundEvents['click']) || undefined

Related

Using typeof in JavaScript still causes error for undefined object

Hi i'm querying Amazon API and every now and again an item doesn't have an image. I'm trying to account for this but i still get the error: TypeError: Cannot read property '0' of undefined
if (typeof result.ItemSearchResponse.Items[0].Item[i].SmallImage[0].URL[0] !== undefined) {
//items['image'][i] = result.ItemSearchResponse.Items[0].Item[i].LargeImage[0].URL[0];
console.log(result.ItemSearchResponse.Items[0].Item[i].SmallImage[0].URL[0]);
}
If i comment out the if statement the error disappears - is there a better way to use typeof - which would account for the object property not existing at all? Or can anyone give advise on how to solve?
Thanks
typeof always returns a string, so it's
if ( typeof something_to_check !== 'undefined' )
If you check for the actual undefined it fails, as undefined !== "undefined"
As for the error, it means you're trying to access the first index ([0]) of something that isn't defined, either
result.ItemSearchResponse.Items
or
result.ItemSearchResponse.Items[0].Item
or
result.ItemSearchResponse.Items[0].Item[i].SmallImage
or
result.ItemSearchResponse.Items[0].Item[i].SmallImage[0].URL
you have to check each one, if you don't know which one fails
if ( result.ItemSearchResponse.Items &&
result.ItemSearchResponse.Items[0].Item &&
result.ItemSearchResponse.Items[0].Item[i].SmallImage &&
result.ItemSearchResponse.Items[0].Item[i].SmallImage[0].URL
) {
// use
var img = result.ItemSearchResponse.Items[0].Item[i].SmallImage[0].URL[0]
}
If the indices can be wrong, or not an array etc. you have to check for that as well.
Why not use
var arr = results.ItemSearchResponse.Items[0].Item[i].SmallImage || false;
if(arr[0]){
// do some work
}
Since the condition fails if any of the containing arrays do not exist or if no image exists in SmallImage.

Why doesn't this simple javascript statement work to check if the variable exists?

I'm processing some return JSON data.
Sometimes the JSON will return something I can access via
var new_insert_id = data['internal']['new_insert_id'];
But sometimes this part of the json array data will not be returned at all, and so I need to skip this variable being set.
So I've written a simple check to make sure this data exists before trying to set the variable:
if(typeof data['internal']['new_insert_id'] != 'undefined')
{
// if data['internal']['new_insert_id'] is defined, then..
var new_insert_id = data['internal']['new_insert_id'];
}
But when the JSON returns and there is no new_insert_id I am getting the following error:
Uncaught TypeError: Cannot read property 'new_insert_id' of undefined
And the line of code it points to as the culprit is the line of my if statement.
What am I missing? I thought my if statement would check if it exists or not, or do I need to do something else when working with arrays?
Besides you can firstly check for existence of data['internal'], but you can also use the pythonic way, i.e. apply try/catch block:
try {
var new_insert_id = data['internal']['new_insert_id'];
} catch (e) {}
The statement you've written checks if new_insert_id property exists in 'internal', but it doesn't check if 'internal' exists in data variable.
This should work better:
if(typeof data['internal'] != 'undefined' && typeof data['internal']['new_insert_id'] != 'undefined')
{
var new_insert_id = data['internal']['new_insert_id'];
}
the error message says, that data['internal'] is already undefined. you need to check that before:
if(typeof(data['internal']) != 'undefined' && typeof data['internal']['new_insert_id'] != 'undefined')
You need to check data['internal'] !== undefined first :)
in your test, you are testing if the property ['new_insert_id'] of data['internal'] is undefined then you have trouble accessing it because data['internal'] is undefined hence the error you get.
You have first to check if data['internal'] is undefined.
I think it because data['internal'] is undefined.
So you need check data['internal'] first.
if(data['internal'] && data['internal']['new_insert_id'])
{
// if data['internal']['new_insert_id'] is defined, then..
var new_insert_id = data['internal']['new_insert_id'];
}

Why is this check throwing an error, even if I check whether it’s undefined beforehand?

I passed in a series of JSON objects with an AJAX call. Some of the data sets include the field C and some do not. When I include the following code, it crashes. I have tried undefined and null. Both crash.
if (myJsonObjects[i].C == undefined) {
// …
}
When you say crash I presume you mean TypeError: cannot read property of undefined value
The reason it crashes is because in the line
if(myJsonObjects[i].C == undefined){
We actually have myJSONObject[i] === undefined
So really you need to check your array bounds or make sure your array is not sparse
if(myJsonObjects[i].C == undefined){
is the similar as
if(myJsonObjects[i] && myJsonObjects[i].C){
but with mine line, you check is myJsonObjects[i] and myJsonObjects[i].c are null or undefined.
The caveat being if myJsonObjects[i].c holds false, "", 0, NaN
Try this:
if (typeof myJsonObjects[i].C == 'undefined') {}
I guess you could test the waters a little before jumping right in:
if( i in myJsonObjects && myJsonObjects[i] && !( "C" in myJsonObjects[i] ) ) { }
However your original code should not crash and shouldn't throw error either if myJsonObjects[i] is defined and is not null
How about
if ('C' in myJsonObjects[i]) { do_your_magic() }

Test if something is not undefined in JavaScript

I'm checking if(response[0].title !== undefined), but I get the error:
Uncaught TypeError: Cannot read property 'title' of undefined.
response[0] is not defined, check if it is defined and then check for its property title.
if(typeof response[0] !== 'undefined' && typeof response[0].title !== 'undefined'){
//Do something
}
Just check if response[0] is undefined:
if(response[0] !== undefined) { ... }
If you still need to explicitly check the title, do so after the initial check:
if(response[0] !== undefined && response[0].title !== undefined){ ... }
I had trouble with all of the other code examples above. In Chrome, this was the condition that worked for me:
typeof possiblyUndefinedVariable !== "undefined"
I will have to test that in other browsers and see how things go I suppose.
Actually you must surround it with an Try/Catch block so your code won't stop from working.
Like this:
try{
if(typeof response[0].title !== 'undefined') {
doSomething();
}
}catch(e){
console.log('responde[0].title is undefined');
}
typeof:
var foo;
if (typeof foo == "undefined"){
//do stuff
}
It'll be because response[0] itself is undefined.
Check if condition == null;
It will resolve the problem
Check if you're response[0] actually exists, the error seems to suggest it doesn't.
You must first check whether response[0] is undefined, and only if it's not, check for the rest. That means that in your case, response[0] is undefined.
I know i went here 7 months late, but I found this questions and it looks interesting. I tried this on my browser console.
try{x,true}catch(e){false}
If variable x is undefined, error is catched and it will be false, if not, it will return true. So you can use eval function to set the value to a variable
var isxdefined = eval('try{x,true}catch(e){false}')
In some of these answers there is a fundamental misunderstanding about how to use typeof.
Incorrect
if (typeof myVar === undefined) {
Correct
if (typeof myVar === 'undefined') {
The reason is that typeof returns a string. Therefore, you should be checking that it returned the string "undefined" rather than undefined (not enclosed in quotation marks), which is itself one of JavaScript's primitive types. The typeof operator will never return a value of type undefined.
Addendum
Your code might technically work if you use the incorrect comparison, but probably not for the reason you think. There is no preexisting undefined variable in JavaScript - it's not some sort of magic keyword you can compare things to. You can actually create a variable called undefined and give it any value you like.
let undefined = 42;
And here is an example of how you can use this to prove the first method is incorrect:
https://jsfiddle.net/p6zha5dm/

When to check for undefined and when to check for null

[Bounty Edit]
I'm looking for a good explanation when you should set/use null or undefined and where you need to check for it. Basically what are common practices for these two and is really possible to treat them separately in generic maintainable codee?
When can I safely check for === null, safely check for === undefined and when do I need to check for both with == null
When should you use the keyword undefined and when should one use the keyword null
I have various checks in the format of
if (someObj == null) or if (someObj != null) which check for both null and undefined. I would like to change all these to either === undefined or === null but I'm not sure how to guarantee that it will only ever be one of the two but not both.
Where should you use checks for null and where should you use checks for undefined
A concrete example:
var List = []; // ordered list contains data at odd indexes.
var getObject = function(id) {
for (var i = 0; i < List.length; i++) {
if (List[i] == null) continue;
if (id === List[i].getId()) {
return List[i];
}
}
return null;
}
var deleteObject = function(id) {
var index = getIndex(id) // pretty obvouis function
// List[index] = null; // should I set it to null?
delete List[index]; // should I set it to undefined?
}
This is just one example of where I can use both null or undefined and I don't know which is correct.
Are there any cases where you must check for both null and undefined because you have no choice?
Functions implicitly return undefined. Undefined keys in arrays are undefined. Undefined attributes in objects are undefined.
function foo () {
};
var bar = [];
var baz = {};
//foo() === undefined && bar[100] === undefined && baz.something === undefined
document.getElementById returns null if no elements are found.
var el = document.getElementById("foo");
// el === null || el instanceof HTMLElement
You should never have to check for undefined or null (unless you're aggregating data from both a source that may return null, and a source which may return undefined).
I recommend you avoid null; use undefined.
Some DOM methods return null. All properties of an object that have not been set return undefined when you attempt to access them, including properties of an Array. A function with no return statement implicitly returns undefined.
I would suggest making sure you know exactly what values are possible for the variable or property you're testing and testing for these values explicitly and with confidence. For testing null, use foo === null. For testing for undefined, I would recommend using typeof foo == "undefined" in most situations, because undefined (unlike null) is not a reserved word and is instead a simple property of the global object that may be altered, and also for other reasons I wrote about recently here: variable === undefined vs. typeof variable === "undefined"
The difference between null and undefined is that null is itself a value and has to be assigned. It's not the default. A brand new variable with no value assigned to it is undefined.
var x;
// value undefined - NOT null.
x = null;
// value null - NOT undefined.
I think it's interesting to note that, when Windows was first written, it didn't do a lot of checks for invalid/NULL pointers. Afterall, no programmer would be dumb enough to pass NULL where a valid string was needed. And testing for NULL just makes the code larger and slower.
The result was that many UAEs were due to errors in client programs, but all the heat went to Microsoft. Since then, Microsoft has changed Windows to pretty much check every argument for NULL.
I think the lesson is that, unless you are really sure an argument will always be valid, it's probably worth verifying that it is. Of course, Windows is used by a lot of programmers while your function may only be used by you. So that certainly factors in regarding how likely an invalid argument is.
In languages like C and C++, you can use ASSERTs and I use them ALL the time when using these languages. These are statements that verify certain conditions that you never expect to happen. During debugging, you can test that, in fact, they never do. Then when you do a release build these statements are not included in the compiled code. In some ways, this seems like the best of both worlds to me.
If you call a function with no explicit return then it implicitly returns undefined. So if I have a function that needs to say that it did its task and there is nothing result, e.g. a XMLHTTPRequest that returned nothing when you normally expect that there would be something (like a database call), then I would explicitly return null.
Undefined is different from null when using !== but not when using the weaker != because JavaScript does some implicit casting in this case.
The main difference between null and undefined is that undefined can also mean something which has not been assigned to.
undefined false
(SomeObject.foo) false false
(SomeObject.foo != null) false true
(SomeObject.foo !== null) true true
(SomeObject.foo != false) true false
(SomeObject.foo !== false) true false
This is taken from this weblog
The problem is that you claim to see the difference, but you don't. Take your example. It should really be:
var List = []; // ordered list contains data at odd indexes.
var getObject = function(id) {
for (var i = 1; i < List.length; i+=2) {
if (id === List[i].getId()) {
return List[i];
}
}
// returns undefined by default
}
Your algorithm is flawed because you check even indexes (even though you know there's nothing there), and you also misuse null as a return value.
These kind of functions should really return undefined because it means: there's no such data
And there you are in the heart of the problem. If you don't fully understand null and undefined and may use them wrongly sometimes, how can you be so sure that others will use it correctly? You can't.
Then there are Host objects with their nasty behavior, if you ask me, you better off checking for both. It doesn't hurt, in fact, it saves you some headaches dealing with third party code, or the aformentioned non-native objects.
Except for these two cases, in your own code, you can do what #bobince said:
Keep undefined as a special value for signalling when other languages might throw an exception instead.
When to set/use them...
Note that a method without a return statement returns undefined, you shouldn't force this as an expected response, if you use it in a method that should always return a value, then it should represent an error state internally.
Use null for an intentional or non-match response.
As for how/when to check...
undefined, null, 0, an empty string, NaN and false will be FALSE via coercion. These are known as "falsy" values... everything else is true.
Your best bet is coercion then testing for valid exception values...
var something; //undefined
something = !!something; //something coerced into a boolean
//true if false, null, NaN or undefined
function isFalsish(value) {
return (!value && value !== "" && value !== 0);
}
//get number or default
function getNumber(val, defaultVal) {
defaultVal = isFalsish(defaultVal) ? 0 : defaultVal;
return (isFalsish(val) || isNaN(val)) ? defaultVal : +val;
}
Numeric testing is the real bugger, since true, false and null can be coerced into a number, and 0 coerces to false.
I would treat them as 2 completely different values, and check for the one you know might occur.
If you're checking to see if something has been given a value yet, check against undefined.
If you're checking to see if the value is 'nothing,' check against 'null'
A slightly contrived example:
Say you have a series of ajax requests, and you're morally opposed to using callbacks so you have a timeout running that checks for their completion.
Your check would look something like this:
if (result !== undefined){
//The ajax requests have completed
doOnCompleteStuff();
if (result !== null){
//There is actually data to process
doSomething(result);
}
}
tldr; They are two different values, undefined means no value has been given, null means a value has been given, but the value is 'nothing'.

Categories