Categories
JavaScript Answers

How to Test for Existence of Nested JavaScript Object Key?

Spread the love

JavaScript objects are often nested in other objects.

Also, they’re dynamic.

Therefore, we may have to check if a nested property exists in an object.

In this article, we’ll look at how to check if a nested property exists in an object.

Write Our Own Function

We can write our own JavaScript function to check if a deeply nested property exists in an object.

For instance, we can write:

const checkNested = (obj, ...props) => {
  for (const prop of props) {
    if (!obj || !Object.prototype.hasOwnProperty.call(obj, prop)) {
      return false;
    }
    obj = obj[prop];
  }
  return true;
}

const obj = {
  level1: {
    level2: {
      level3: 'level3'
    }
  }
};

console.log(checkNested(obj, 'level1', 'level2', 'level3'));
console.log(checkNested(obj, 'level1', 'level2', 'bar'));

We create the checkNested function with the obj parameter and the props rest parameters.

obj is the object we’re checking.

props has an array of properties that forms the path to the nested property we’re looking for.

In the function, we loop through the props array to traverse obj to find the nested property.

To do that, we check if obj is falsy or if hasOwnProperty returns false .

If either of them are true , then we know the property doesn’t exist.

So we return false .

We call hasOwnProperty with Object.prototype.hasOwnProperty.call instead of obj.hasOwnProperty since obj.hasOwnProperty can be overridden.

call takes the this value for hasOwnProperty .

prop is the property name string value.

If we get past the if block, then we assign obj to obj[prop] to look one level deeper.

We can do that since the property is an object.

If the whole loop is iterated through successfully, then we return true since the path leads to the property we’re looking for.

We test this function with the obj object, and we can see the first console returns true .

And the 2nd one returns false as expected.

Recursively Check for a Given Property

We can also do the check with a recursive function.

For instance, we can write:

const checkNested = (obj, prop, ...restProps) => {
  if (obj === undefined) {
    return false;
  }
  if (
    restProps.length === 0 &&
    Object.prototype.hasOwnProperty.call(obj, prop)
  ) {
    return true;
  }
  return checkNested(obj[prop], ...restProps);
};

const obj = {
  level1: {
    level2: {
      level3: "level3"
    }
  }
};

console.log(checkNested(obj, "level1", "level2", "level3"));
console.log(checkNested(obj, "level1", "level2", "foo"));

This checkNested function is similar to the one we have before.

The difference is that we get the first property from the path we’re looking for.

And the rest stays in the array.

We check if restProp.length is 0 and if obj has the prop property.

If they’re both true , then we return true since we traversed the whole path and we found the property.

If they’re anything left in restProps , then we call checkNested to drill down one level lower.

And we should get the same result as before.

Optional Chaining Operator

Another way to check if a nested property path exists is to use tyhe optional chaining operator, which is added with ?. .

This operator is new to ES2020.

For instance, we can write:

const obj = {
  level1: {
    level2: {
      level3: "level3"
    }
  }
};

const value1 = obj?.level1?.level2?.level3;
const value2 = obj?.level1?.level2?.foo;
console.log(value1);
console.log(value2);

We should see that value1 is 'level3' and value2 is undefined since the operator returns the property value if the property exists and undefined otherwise.

This lets us reduce the amount of work needed to traverse deeply nested properties safely.

Conclusion

We can test for the existence of a deeply nested JavaScript object property with our own code or the optional chaining operator.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *