Test For Existence of Nested JavaScript Object Key

Test for existence of nested JavaScript object key

You have to do it step by step if you don't want a TypeError because if one of the members is null or undefined, and you try to access a member, an exception will be thrown.

You can either simply catch the exception, or make a function to test the existence of multiple levels, something like this:

function checkNested(obj /*, level1, level2, ... levelN*/) {
var args = Array.prototype.slice.call(arguments, 1);

for (var i = 0; i < args.length; i++) {
if (!obj || !obj.hasOwnProperty(args[i])) {
return false;
}
obj = obj[args[i]];
}
return true;
}

var test = {level1:{level2:{level3:'level3'}} };

checkNested(test, 'level1', 'level2', 'level3'); // true
checkNested(test, 'level1', 'level2', 'foo'); // false

ES6 UPDATE:

Here is a shorter version of the original function, using ES6 features and recursion (it's also in proper tail call form):

function checkNested(obj, level,  ...rest) {
if (obj === undefined) return false
if (rest.length == 0 && obj.hasOwnProperty(level)) return true
return checkNested(obj[level], ...rest)
}

However, if you want to get the value of a nested property and not only check its existence, here is a simple one-line function:

function getNested(obj, ...args) {

return args.reduce((obj, level) => obj && obj[level], obj)

}

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

console.log(getNested(test, 'level1', 'level2', 'level3')); // 'level3'

console.log(getNested(test, 'level1', 'level2', 'level3', 'length')); // 6

console.log(getNested(test, 'level1', 'level2', 'foo')); // undefined

console.log(getNested(test, 'a', 'b')); // undefined

JavaScript: Check for existence of key in nested objects when its path is unknown

One approach would be with a recursive search function like doesObjectHaveNestedKey() as shown below ( which this does not require an extra dependency like lodash ):

const object = {

some : {

nested : {

property : {

to : [

{

find : {

foo : [ 1 , 2 , 3 ]

}

}

]

}

}

}

}

/* Define function to recursively search for existence of key in obj */

function doesObjectHaveNestedKey(obj, key) {

if(obj === null || obj === undefined) {

return false;

}



for(const k of Object.keys(obj)) {



if(k === key) {

/* Search keys of obj for match and return true if match found */

return true

}

else {

const val = obj[k];



/* If k not a match, try to search it's value. We can search through

object value types, seeing they are capable of containing

objects with keys that might be a match */

if(typeof val === 'object') {



/* Recursivly search for nested key match in nested val */

if(doesObjectHaveNestedKey(val, key) === true) {

return true;

}

}

}

}



return false;

}

console.log('has foo?', doesObjectHaveNestedKey(object, 'foo') ) // True

console.log('has bar?', doesObjectHaveNestedKey(object, 'bar') ) // False

console.log('has nested?', doesObjectHaveNestedKey(object, 'nested') ) // True

console.log('has cat?', doesObjectHaveNestedKey(null, 'cat') ) // False

Get if an object's keys exist in nested objects and arrays

If you really want to be able to check if the key exists anywhere inside the object recursively, you'll need a recursive function.

const myObject = {
name: 'Joe',
favorites: {
ice_cream: 'vanilla',
coffee: 'espresso'
}
};

const getKeys = (obj, keys = [], visited = new Set()) => {
if (visited.has(obj)) return;
visited.add(obj);
keys.push(...Object.keys(obj));
for (const val of Object.values(obj)) {
if (val && typeof val === 'object') {
getKeys(val, keys, visited);
}
}
return keys;
};
console.log(getKeys(myObject));
console.log(getKeys(myObject).includes('coffee'));

Test for existence of nested JavaScript object key

You have to do it step by step if you don't want a TypeError because if one of the members is null or undefined, and you try to access a member, an exception will be thrown.

You can either simply catch the exception, or make a function to test the existence of multiple levels, something like this:

function checkNested(obj /*, level1, level2, ... levelN*/) {
var args = Array.prototype.slice.call(arguments, 1);

for (var i = 0; i < args.length; i++) {
if (!obj || !obj.hasOwnProperty(args[i])) {
return false;
}
obj = obj[args[i]];
}
return true;
}

var test = {level1:{level2:{level3:'level3'}} };

checkNested(test, 'level1', 'level2', 'level3'); // true
checkNested(test, 'level1', 'level2', 'foo'); // false

ES6 UPDATE:

Here is a shorter version of the original function, using ES6 features and recursion (it's also in proper tail call form):

function checkNested(obj, level,  ...rest) {
if (obj === undefined) return false
if (rest.length == 0 && obj.hasOwnProperty(level)) return true
return checkNested(obj[level], ...rest)
}

However, if you want to get the value of a nested property and not only check its existence, here is a simple one-line function:

function getNested(obj, ...args) {

return args.reduce((obj, level) => obj && obj[level], obj)

}

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

console.log(getNested(test, 'level1', 'level2', 'level3')); // 'level3'

console.log(getNested(test, 'level1', 'level2', 'level3', 'length')); // 6

console.log(getNested(test, 'level1', 'level2', 'foo')); // undefined

console.log(getNested(test, 'a', 'b')); // undefined

Find if key or value exist in the array's nested objects

Since you're working with a simple object the JSON.stringify method should come quite handy here. It constructs a json string that contains the entire object, and therefore all the keys and values you have in your object. With that string you can extract every key or value by a regex match.

This is how it may look like:

function findCar(parameter) {
const keysAndValues = JSON.stringify(data).match(/"([^"]+)"/g);
for (let entry of keysAndValues) if (entry.includes(parameter)) return true;
return false;
}

The regex here matches for every entry that starts with ", then only characters that are not " and followed by a ".

Check if certain Javascript object key has exact nested values and then update specific nested value

You could do it like this:

const cart = {
"98eb9514-f403-4d08-b5f7-dd6a5ec013cb":{"quantity":1,"FirstName":"John", "LastName":"Lewis"},
"92ef2918-6bc2-4f3b-b9b3-acf6ebe74b1f":{"quantity":1,"FirstName":"Matthew", "LastName":"Smith"}
}
const productId = "92ef2918-6bc2-4f3b-b9b3-acf6ebe74b1f";
const firstName = "Matthew";
const lastName = "Smith";
const quantity = 1;

const cartItem = cart[productId];

if(typeof cartItem !== "undefined" && cartItem.FirstName === firstName && cartItem.LastName === lastName && cartItem.quantity >= 1) {
cartItem.quantity += 1;
};

console.log(cart);

What's the simplest approach to check existence of deeply-nested object property in JavaScript?

If you expect YAHOO.Foo.Bar to be a valid object, but want to make your code bulletproof just in case it isn't, then it can be cleanest to just put a try catch around it and let one error handler catch any missing segment. Then, you can just use one if condition instead of four that will detect if the terminal property exists and a catch handler to catch things if the intermediate objects don't exist:

try {
if (YAHOO.Foo.Bar.xyz) {
// operate on YAHOO.Foo.Bar.xyz
} catch(e) {
// handle error here
}

or, depending upon how your code works, it might even just be this:

try {
// operate on YAHOO.Foo.Bar.xyz
} catch(e) {
// do whatever you want to do when YAHOO.Foo.Bar.xyz doesn't exist
}

I particularly use these when dealing with foreign input that is supposed to be of a particular format, but invalid input is a possibility that I want to catch and handle myself rather than just letting an exception propagate upwards.

In general, some javascript developers under-use try/catch. I find that I can sometimes replace 5-10 if statements checking input with a single try/catch around a larger function block and make the code a lot simpler and more readable at the same time. Obviously, when this is appropriate depends upon the particular code, but it's definitely worth considering.

FYI, if the usual operation is to not throw an exception with the try/catch, it can be a lot faster than a bunch of if statements too.


If you don't want to use the exception handler, you can create a function to test any arbitrary path for you:

function checkPath(base, path) {
var current = base;
var components = path.split(".");
for (var i = 0; i < components.length; i++) {
if ((typeof current !== "object") || (!current.hasOwnProperty(components[i]))) {
return false;
}
current = current[components[i]];
}
return true;
}

Example usage:

var a = {b: {c: {d: 5}}};
if (checkPath(a, "b.c.d")) {
// a.b.c.d exists and can be safely accessed
}

Checking existence of nested property in an object javascript

You can explore your Obj with this function :

var fn = function(obj, props) {
var splited = props.split('.');
var temp = obj;
for(var index in splited) {
if(typeof temp[splited[index]] === 'undefined') return false;
temp = temp[splited[index]]
}
return true
}

var result = fn({ }, "toto.tata");
console.log(result); // false

var result = fn({ toto: { tata: 17 } }, "toto.tata");
console.log(result); // true

var result = fn({ toto: { tata: { tutu: 17 } } }, "toto.foo.tata");
console.log(result); // false

This function allow to explore nested property of Obj that depends of props passed in parameter

JavaScript, elegant way to check nested object properties for null/undefined

You can use an utility function like this:

get = function(obj, key) {
return key.split(".").reduce(function(o, x) {
return (typeof o == "undefined" || o === null) ? o : o[x];
}, obj);
}

Usage:

 get(user, 'loc.lat')     // 50
get(user, 'loc.foo.bar') // undefined

Or, to check only if a property exists, without getting its value:

has = function(obj, key) {
return key.split(".").every(function(x) {
if(typeof obj != "object" || obj === null || ! x in obj)
return false;
obj = obj[x];
return true;
});
}

if(has(user, 'loc.lat')) ...

Check if key exists in nested object

You can use a recursive approach (DFS) to find the object next to your key. If a non-null object is returned, you can get its hide value:

const data = {

status: {

cause_of_death: {

hide: true,

other_cause_of_death: {

hide: true

}

},

date_of_birth: {

hide: true

}

}

};

function findKey(obj, key) {

if (typeof obj !== 'object') return null;

if (key in obj) return obj[key];

for (var k in obj) {

var found = findKey(obj[k], key);

if (found) return found;

}

return null;

}

console.log(findKey(data, 'date_of_birth'));

console.log(findKey(data, 'cause_of_death'));

console.log(findKey(data, 'other_cause_of_death'));

console.log(findKey(data, 'hello'));


Related Topics



Leave a reply



Submit