Matt Foxx Duncan
Matt Foxx Duncan

Reputation: 2094

ES6 default parameters on a nullable nested object while destructuring

I have an object like this

const obj = {
  foo: {
    bar: { // maybe null
      id: 0
    }
  }
};

I want to destructure obj to get id. If bar was only ever undefined or an object this would be sufficient:

const {
        foo: {
          bar: {
            id,
          } = {},
        } = {},
      } = obj;

But when bar is null I get the error Cannot read property 'id' of null.

I could do this, suggested here

const {
        foo: {
          bar = {},
        } = {},
      }      = obj;
const { id } = bar || {};

but this means I would need to destructure every nullable object as a separate statement, which I'd prefer not to do.

Is there a way to make the default initializer for an object run if its value is null?

Upvotes: 2

Views: 593

Answers (1)

0xc14m1z
0xc14m1z

Reputation: 3725

You can sort of "hijack" the spread operator. You'll have a not-so-beatiful syntax like but it works:

const obj = {
  foo: {
    bar: null
  }
}

const id = {...{...{...obj}.foo}.bar}.id
// id = undefined

You can add an "or something" to the end to get a default value, like:
const id = {...{...{...obj}.foo}.bar}.id || 42
// id = 42

The principle on how this works is that if you try to spread an undefined or null value, you'll get an empty object:

console.log('spreaded null', { ...null })
// {}

console.log('spreaded undefined', { ...undefined })
// {}

Now, if you access a property that isn't defined on an object, the JS engine will return you undefined, thus, you can spread it to have another empty object to chain the next inner property you need to access.

Upvotes: 3

Related Questions