How to avoid 'cannot read property of undefined' errors?

124

In my code, I deal with an array that has some entries with many objects nested inside one another, where as some do not. It looks something like the following:

// where this array is hundreds of entries long, with a mix
// of the two examples given
var test = [{'a':{'b':{'c':"foo"}}}, {'a': "bar"}];

This is giving me problems because I need to iterate through the array at times, and the inconsistency is throwing me errors like so:

for (i=0; i<test.length; i++) {
    // ok on i==0, but 'cannot read property of undefined' on i==1
    console.log(a.b.c);
}

I am aware that I can say if(a.b){ console.log(a.b.c)}, but this is extraordinarily tedious in cases where there are up to 5 or 6 objects nested within one another. Is there any other (easier) way that I can have it ONLY do the console.log if it exists, but without throwing an error?

This question is tagged with javascript

~ Asked on 2013-02-08 22:16:00

The Best Answer is


140

Update:

  • If you use JavaScript according to ECMAScript 2020 or later, see optional chaining.
  • TypeScript has added support for optional chaining in version 3.7.
// use it like this
obj?.a?.lot?.of?.properties

Solution for JavaScript before ECMASCript 2020 or TypeScript older than version 3.7:

A quick workaround is using a try/catch helper function with ES6 arrow function:

_x000D_
_x000D_
function getSafe(fn, defaultVal) {
  try {
    return fn();
  } catch (e) {
    return defaultVal;
  }
}

// use it like this
console.log(getSafe(() => obj.a.lot.of.properties));

// or add an optional default value
console.log(getSafe(() => obj.a.lot.of.properties, 'nothing'));
_x000D_
_x000D_
_x000D_

~ Answered on 2017-02-20 16:23:14


50

What you are doing raises an exception (and rightfully so).

You can always do

try{
   window.a.b.c
}catch(e){
   console.log("YO",e)
}

But I wouldn't, instead think of your use case.

Why are you accessing data, 6 levels nested that you are unfamiliar of? What use case justifies this?

Usually, you'd like to actually validate what sort of object you're dealing with.

Also, on a side note you should not use statements like if(a.b) because it will return false if a.b is 0 or even if it is "0". Instead check if a.b !== undefined

~ Answered on 2013-02-08 22:18:19


Most Viewed Questions: