0

I'm working with two objects in JS and I need to know if a given subobject exists. My objects look something like this:

obj1 = {
   sobj1: 1234,
   sobj2: {
      ssobj1: "abc",
      ssobj2: 1234
   }
}

The catch is that I don't know beforehand the exact shape of the object and when I try to check if ssojb1 exists with an if (obj1.sobj2.ssobj1) and sobj2 isn't set, I'll get an error like "trying to read property ssobj1 of undefined.

To circumvent this, my approach was to use a cascade of if statements, but I'm pretty sure that there's a better option. This can get ugly pretty quickly.

Any suggestions?

Murilo Schünke
  • 106
  • 2
  • 7
  • 1
    Does this answer your question? [How do I check if an object has a key in JavaScript?](https://stackoverflow.com/questions/455338/how-do-i-check-if-an-object-has-a-key-in-javascript) – mousetail Jun 24 '20 at 18:58
  • https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining, not sure if widely supported yet. Lodash also has a `get` where you can specify a path and a default value https://lodash.com/docs/4.17.15#get – Anthony Jun 24 '20 at 19:02
  • @mousetail yes it does! Thank you – Murilo Schünke Jun 24 '20 at 20:47

2 Answers2

0

There is an optional chaining operator supported in modern browsers ?., but you may still be working with if statements at that point. In these cases, utilities may help you.

const isDefined = x => typeof x !== 'undefined'

const { get } = rubico

const pathsToCheck = [
  'sobj2.ssobj1',
  'sobj2.ssobj3',
]

const checkPath = (path, obj) => isDefined(get(path)(obj))

const obj1 = {
   sobj1: 1234,
   sobj2: {
      ssobj1: "abc",
      ssobj2: 1234
   }
}

for (const path of pathsToCheck) {
  console.log(path, checkPath(path, obj1))
}
<script src="https://unpkg.com/rubico"></script>

Disclaimer: I am the author of rubico.

Documentation for get

richytong
  • 2,387
  • 1
  • 10
  • 21
0

Thanks to mousetail for the solution.

Appearently using if ('key' in obj) does the trick, even if obj is undefined.

So:

if ('ssobj1' in obj1) {   // true or false
   do stuff...
}
Murilo Schünke
  • 106
  • 2
  • 7