-3

Suppose we want the value in variable val.

Scenario 1 :

Var ObjectA = {ObjectB:{val:"text"}}

if we want to get value in val, we can access like ObjectA.ObjectB.val. And We'll get "text"

Scenario 2:

Var ObjectB = {}

if I want to get value in val (which is not there), And If I try to access like ObjectA.ObjectB.val We'll get

Uncaught TypeError: Cannot read property 'val' of undefined at :1:5

The rules are

  1. we cannot make any values null or initialise any values, We'll simply get these values and must use them.
  2. If ObjectB exists inside ObjectA it doesn't means that val exists inside the ObjectB.

All I want to know is just if there exists a value in variable val or not without disturbing any other things.

DjaouadNM
  • 22,013
  • 4
  • 33
  • 55
  • Why can't you just chain access? ObjectA && ObjectA.ObjectB && ObjectA.ObjectB.val or equivalent using any path-based lib etc? – Dave Newton Aug 29 '19 at 21:05
  • Don't do "the rules are". That's code golf. Stack Overflow is not for code golfing. – new Q Open Wid Aug 29 '19 at 21:11
  • 1
    https://stackoverflow.com/questions/2631001/test-for-existence-of-nested-javascript-object-key – epascarello Aug 29 '19 at 21:12
  • @zixuan this would promptly be closed as off-topic on Code Golf due to non-objective scoring criteria... – Patrick Roberts Aug 29 '19 at 21:12
  • @PatrickRoberts Clearly, you can see "the rules are". I'm not saying this should be migrated to Code Golf, I'm just saying that I would change that part of the question to something different. – new Q Open Wid Aug 29 '19 at 21:15
  • @zixuan It wasn't clear to me that you _weren't_ suggesting a migration in your previous comment. – Patrick Roberts Aug 29 '19 at 21:16
  • Possible duplicate of [Test for existence of nested JavaScript object key](https://stackoverflow.com/questions/2631001/test-for-existence-of-nested-javascript-object-key) – new Q Open Wid Aug 29 '19 at 21:18

2 Answers2

2

I would do this by checking each thing in sequence:

if(ObjectA && ObjectA.ObjectB && ObjectA.ObjectB.val) {
    // Do something with ObjectA.ObjectB.val
}

If that construction is too clumsy for you, then two other possibilities come to mind:

  • Fill in a default value at each stage, i.e. ((ObjectA || {}).ObjectB || {}).val
  • Test only the innermost value, but inside a try...catch block (and silently discard the inevitable error if one of the outer values is missing).

However, those are both harder to read and less performant than the &&-chaining version, so I would only consider them if your chain is very long.

Brilliand
  • 13,404
  • 6
  • 46
  • 58
  • With the [optional chaining proposal](https://github.com/tc39/proposal-optional-chaining) this can be simplified to `ObjectA?.ObjectB?.val` – Patrick Roberts Aug 29 '19 at 21:06
  • @PatrickRoberts Does that proposal have any support in web browsers at this point? – Brilliand Aug 29 '19 at 21:08
  • Not that I'm aware of but there is a [babel plugin](https://babeljs.io/docs/en/babel-plugin-proposal-optional-chaining) that allows you to use it in projects where the codebase is already being transpiled. – Patrick Roberts Aug 29 '19 at 21:11
0

If the key you are looking for is too nested you could use a tool like get from lodash (you can also add a default value if the key isn't there).

Either way you can check for existence like this:

let myVal = null;
if (ObjectA && ObjectA.ObjectB && ObjectA.ObjectB.val) myVal = val;

Some caveats of this solution is that if val is valued to false, for example if the value is 0 or false (You can read more about it here) the value will still be null. You can avoid this by using the unary operator typeof:

let myVal = null;
if (typeof ObjectA !== "undefined" && typeof ObjectA.ObjectB !== "undefined" && typeof ObjectA.ObjectB.val !== "undefined") myVal = val;
damjtoh
  • 365
  • 1
  • 7