0

I wonder if there is some way to use hasOwnProperty for an object for multiple levels.

To illustrate: I have following object:

var Client = { ID: 1, Details: { Title: 'Dr', Sex: 'male' } } 

I can now do the following in javascript:

('Title' in Client.Details) -> true 

However I cannot! do:

('Street' in Client.Adress) 

...yet I must first use an if to not throw an error. Because I might have a large object - I only need to know if there is "Adress" in Client.Details without using prior if statements, any idea if that is possible?

// this is overkill -> (will be many more if-statements for checking a lower level if('Adress' in Client){ console.log('Street' in Client.Adress) } else { console.log(false) } 

Example which produces the error:

var Client = { ID: 1, Details: { Title: 'Dr', Sex: 'male' } } // Results in Error: ('Street' in Client.Adress) // Results in Error: if('Street' in Client.Adress){}

8
  • 2
    console.log('Adress' in Client && 'Street' in Client.Adress)? Commented Sep 13, 2018 at 13:48
  • I have added an example for you that shows there is an error Commented Sep 13, 2018 at 14:03
  • Yes I see that there's an error. But no, it's not overkill to check for every property that you are accessing, and no you don't need many more if statements for that. Commented Sep 13, 2018 at 14:13
  • Well above is a very simplified example. Imaging an object with 10+ levels and I merely want to know if at level 7 there is object "XYZ" present or not. That would mean 6 (I think) if-statements just to not have the code crash in an error, which in my opinion is overkill Commented Sep 13, 2018 at 14:41
  • No, not if statements! Just chain them together using the && operator. You can put that expression in a single if condition. For alternative approaches see the duplicates Commented Sep 13, 2018 at 14:45

1 Answer 1

4

You could pass the path of your attributes via a String and use a recursive function to run your object down:

const checkPath = (o, path) => { if(path.includes('.')){ if(o.hasOwnProperty(path.split('.')[0])) return checkPath(o[path.split('.')[0]], path.split('.').slice(1).join('.')); else return false }else return o.hasOwnProperty(path); } 

And use it like this :

checkPath(Client, 'Details.Title') 

Demo:

let Client = { ID: 1, Details: { Title: 'Dr', Sex: 'male' } }; const checkPath = (o, path) => { if(path.includes('.')){ if(o.hasOwnProperty(path.split('.')[0])) return checkPath(o[path.split('.')[0]], path.split('.').slice(1).join('.')); else return false }else return o.hasOwnProperty(path); } console.log(checkPath(Client, 'Details.Title')); console.log(checkPath(Client, 'Test.Title'));


Here's the sexy one-liner:

const checkPath = (o, path) => path.includes('.') ? o.hasOwnProperty(path.split('.')[0]) ? checkPath(o[path.split('.')[0]], path.split('.').slice(1).join('.')) : false : o.hasOwnProperty(path); 
Sign up to request clarification or add additional context in comments.

4 Comments

Seems good. Tried with checkPath(Client, 'Details.Address.Drive') and it works. Do you think there is any problems when the object gets more complicated? (containing functions etc.)
@DavidDunham It won't execute functions for you, if that's what you mean. Other than that, it should hold fine.
No I meant if the object complexity (with functions) might break the functionality of your code because it's not "common" to have functions in an object.
As I said, if you check for a path that contains a function, it won't execute it, thus will not continue to check the next attribute.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.