2

If accessing properties of undefined value, I'm getting an exception:

let object = {}
let n = object["foo"].length;

VM186:1 Uncaught TypeError: Cannot read property 'length' of undefined at :1:12

I want to get a default value in this case instead of an exception, but the way I'm doing it now seems too verbose:

let n = 0;
if (object.hasOwnProperty("foo")) {
    n = object["foo"].length;
}

Is there a more simple and elegant way to do this? Possibly, using ES6.

coolvision
  • 35
  • 3

5 Answers5

1

The method mentioned by @lleaon will work only when the value is undefined and won't work for other falsy values like null.

Here is a technique I use often to safely access nested objects in JavaScript. I picked it up a year ago from another SO answer.

const obj = {};
const arrLength = (obj.foo || []) || 0;
console.log(arrLength); // 0

You can check deep nest level like this,

const obj = {};
const arrLength = ((obj.nestedObj || {}).foo || []) || 0;
console.log(arrLength); // 0

In case you're iterested, I wrote a blog post on it a while back.

Safely Accessing Nested Objects in JavaScript

Dinesh Pandiyan
  • 4,702
  • 1
  • 23
  • 42
0

Try ternary operator:

let n =object["foo"] ? object["foo"].length : 0;

To not write twice object["foo"] you can also do something like that:

let n = object["foo"]; 
n = n ? n.length : 0;
Kamil Kiełczewski
  • 53,729
  • 20
  • 259
  • 241
0

using es6 you can check whether any key is there for the object by checking using Object.keys(object) which will give an array of keys Object.keys, checking it with the length will give that object is empty or not and also checking one more condition whether the constructor of object is an Object.

Please see the below code. if those two conditions are satisfied which means object is empty and you can assign a default value

let object = {}
if(Object.keys(object).length === 0 && object.constructor === Object){
// assign a default value if the object is empty
 object["foo"] = "bar"
}

console.log("object is empty default value will be assigned", object)
DILEEP THOMAS
  • 6,108
  • 3
  • 21
  • 56
0

Not sure if more elegant, but object destructuring can assign default values. It wont prevent you from null values though. Just undefined

const obj = {};
const { foo: { length = 0 } = [] } = obj;
  
console.log(length)
lleon
  • 1,889
  • 1
  • 16
  • 14
0

We have two possible undefined values to check. First, the key needs to exist on dictionary. After that, the object should be an array or a struct with the property length.

One great way to go is to use || to define a default value when undefined. But it will not work if you tried to check length of an undefined value, without dealing with this first.

Example

   let object = {};
   
   let r = (object["foo"] || 333);
   let l = r.length || 111;

   let oneLiner = (object["foo"] || 333).length || 111;

   console.log("Default Value: " + r);
   console.log("Default Length: " + l);
   console.log("OneLiner: " + oneLiner);

Another Example

A simpler example, closer of your use case;

   let object = {};
   
   let length = (object["foo"] || []).length;

   console.log(length);
luizv
  • 479
  • 8
  • 16