3

Is there an elegant and concise way to avoid doing something like this to check a value deep within an object member hierarchy in javascript?

handlerInput.supportsDisplay = function() {
   return  this.requestEnvelope.context && 
           this.requestEnvelope.context.System && 
           this.requestEnvelope.context.System.device && 
           this.requestEnvelope.context.System.device.supportedInterfaces && 
           this.requestEnvelope.context.System.device.supportedInterfaces.Display;
}
German
  • 10,263
  • 4
  • 40
  • 56
  • 1
    Possible duplicate of [Test for existence of nested JavaScript object key](https://stackoverflow.com/questions/2631001/test-for-existence-of-nested-javascript-object-key) – t.niese Aug 26 '18 at 17:47

3 Answers3

1

There is currently no concise way to do it in plain JavaScript, unless you use a helper function or a third-party library.

There is a proposal (at Stage 1 as of August 2018) to add the ?. operator to JavaScript which does exactly what you want.

With that proposal accepted, you would be able to use ?. instead of . anywhere where a property might be missing, so your code would become:

// careful: this syntax is not available yet
var hasDisplay = handlerInput.requestEnvelope.context?.System?.device?.supportedInterfaces?.Display
Mikhail Burshteyn
  • 4,762
  • 14
  • 27
  • As a steward of StackOverflow, you should be voting to close as duplicate rather than providing a new answer to something that has been asked and answered thoroughly already. – random_user_name Oct 21 '18 at 18:54
0

This is cheating, but you can use the _.get function from Lodash

_.get(validations, "path.to.nested.prop");

From the docs

Gets the value at path of object. If the resolved value is undefined, the defaultValue is returned in its place.

seebiscuit
  • 4,905
  • 5
  • 31
  • 47
  • I guess he was asking if he could just check the nested value without using dots(a.b.c.d.e.f.g.h) and you did that only just with lodash. – NAVIN Aug 26 '18 at 17:38
  • 2
    I disagree. He wants to do it in one line. That's what you `_.get` – seebiscuit Aug 26 '18 at 17:47
  • 1
    I disagree that it's cheating. The LoDash library makes many, many things clearer and safer. I don't go anywhere without LoDash :) – random_user_name Oct 21 '18 at 18:57
0

I wrote an NPM module that allows you to query by a string path.

https://www.npmjs.com/package/js-path-resolver
http://www.twelvetone.tv/docs/developer-tools/npm-modules/js-path-resolver

Here's a codepen https://codepen.io/Flamenco/pen/xaVKjR/?editors=1111

For your use case:

import resolver from 'js-path-resolver'
const info = resolver(handlerInput, 'requestEnvelope.context.System.device.supportedInterface.Display', {onError:'continue'})
const hasDisplay = info.exists
const display = info.get()

In a nutshell, you split the string, then try to resolve the path, one string at a time. There are all sorts of issues implementing this, such as escaping dots, handling array indexes, etc, so using a library makes life much easier. In this library, you can also set, and delete the resolved path.

Steven Spungin
  • 27,002
  • 5
  • 88
  • 78