Calling Deep Nested Arrays

Viewed 59

I have an expected JSON payload that is fairly deep in nested arrays/objects. As I am assigning variables based on the assumed structure

{
  id: value1,
  name: value2,
  data: {
    status: complete,
    date: 2020 - 06 - 20,
    notes: {
      field1: "user notes",
      field2: "more user notes"
    }
  }
}

In my code I will make a call like this:

var usernote = payload.data.notes.field1 || "No Notes"

But it may occur that the user raised no notes, so the notes object will return as undefined. Is there anyway around this without doing a set of cascading default checks? Some of my calls look like this:

priorityvar = payload.data.form_values["b691"][index]["form_values"]["d54d"]["choice_values"][0]

Any help would be greatly appreciated, I couldnt find a similar answer in my search (but very new to here too). Also I am working in google scripts so I cant use any ES6 stuff.

2 Answers

The only way I can think to avoid multiple checks (since you are using Google Scripts and "cant use any ES6 stuff", is by using a try catch approach.

That will validate the whole expression for you, so you don't worry about individual key validations in your object:

var usernote;

try {
  usernote = payload.data.notes.field1;
} catch (error) {
  usernote = "No Notes";
}

For people that can use newer technology

The new ECMA Script 2020 was just released last week and now optional chaining is an official thing.

It allows you to do things like this and not worry if any of those values is undefined:

var usernote = payload?.data?.notes?.field1 || "No Notes"

From the documentation:

The optional chaining operator permits reading the value of a property located deep within a chain of connected objects without having to expressly validate that each reference in the chain is valid

You can use lodash's _.get(obj, path, defaultValue) function. It will try to access the value inside an object that matches given path. Here some examples from the offical documentation.

var object = { 'a': [{ 'b': { 'c': 3 } }] };
 
_.get(object, 'a[0].b.c');
// => 3
 
_.get(object, ['a', '0', 'b', 'c']);
// => 3
 
_.get(object, 'a.b.c', 'default');
// => 'default'

If you cannot import lodash, try to implement one.

P.S. Carelessly I posted the link that linked to the Chinese doc. I have updated it and it links to the English version now.

Related