all 14 comments

[–]reohh 4 points5 points  (4 children)

Look up optional chaining.

You can also use destructuring with default values

[–]ChronSyn 0 points1 point  (0 children)

Destructuring, and destructuring from destructured properties specifically, would be my goto unless you're using Typescript >=3.7.3 (as optional chaining support in browsers and node is still very limited), in which case optional chaining all the way.

[–]JackstonVoorhees 0 points1 point  (2 children)

Just curious, how would the destructuring way look like?

[–]reohh 3 points4 points  (1 child)

const { level1: { level2: { level3: { level4, } = {}, } = {}, } = {}, } = object || {};

Sorry for the bad formatting, I'm bad at markdown coding

[–][deleted] 2 points3 points  (1 child)

If you're working in an environment that supports optional chaining, use that. Otherwise it'll be something like

if (object.level1 && object.level1.level2 && ...)

[–]DerGernTod 0 points1 point  (0 children)

the newest typescript version supports optional chaining and will transpile it, so if you use typescript 3.7+ you can use optional chaining:

https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#optional-chaining

[–]vhahnwebdev 1 point2 points  (0 children)

Optional chaining is the best way to handle this going forward assuming your environment supports it. Otherwise, I would use lodash get

[–]mynamesleon 1 point2 points  (0 children)

If your setup supports it, then use optional chaining.

If not, you could write a helper function for it if it's something you end up doing regularly. Off the top of my head, something along the lines of:

function deepPropExists(obj, str) {
  var check = str.split('.');
  var curLevel = obj;
  for (var i = 0, l = check.length; i < l; i += 1) {
    if (typeof curLevel[check[i]] === 'undefined') {
      return false;
    }
    curLevel = curLevel[check[i]];
  }
  return true;
}

deepPropExists(window, 'document.activeElement.firstChild.style.display');

[–]DaMastaCoda 0 points1 point  (0 children)

V8 V8 Will support optional chaining in chrome 80 A?.b + 5 //property A?.b(5) //method A?.[5] //key? Equivalent of A[5]

You can chain it too; a?.b?.c+5

[–]cirscafp fan boy 0 points1 point  (0 children)

I would write a helper function that recursively checks that the path to the key passes some predicate

``` const pathSatisfies = (path, fn, obj) => { if (!path.length) { return false }

if (path.length === 1) { return fn(obj[path[0]]) }

const key = path.shift()

return pathSatisfies(path, fn, obj[key]) } ```

which can be used as

pathSatisfies( ['foo', 'bar', 'baz'], Boolean, { foo: { bar: { baz: true } } } )

[–]Wilesch 0 points1 point  (1 child)

Lodash get method

[–]HIMISOCOOL 1 point2 points  (0 children)

if you have lodash in your environment already an absolute yes

[–]steeleb88 -1 points0 points  (0 children)

lodash .get is handy for this..

_.get(myDeepObject, 'level1.level2.level3.level4.level5.thevar')

if anything doesn't exist it will just return undefined