8

I have a simple use-case, but I think it's not possible with ES6 syntax. I'd like to use object destructuring to retrieve certain known properties from a nested object, but I'd also like a reference to that nested object so that I can pass it along to other functions which may care about other properties.

Here's an example object:

var record = {
    name: "foo",
    metadata: {
        createdDate: "2017-02-19",
        lastModifiedDate: "2018-07-24",
        type: "bar"
    }
};

At a certain point in my code, I'd like to extract some values from the metadata. At the same time, I'd also like to extract the entire metadata object:

let {
    metadata: {
        createdDate
    }
} = record;

if ( date( createdDate ).before( NEW_FEATURE_DATE ) ){
    oldFeature( metadata );
} else {
    newFeature( metadata );
}

Unfortunately, my reference to the metadata property is used purely for destructuring... it's value is undefined (technically, being undefined, it has no value).

I know I can solve this with something like

let {
        metadata: {
            createdDate
        }
    } = record,
    metadata = record.metadata;

or

let {
        metadata
    } = record,
    {
        createdDate
    } = metadata;

... but that seems kind of clumsy, doesn't it? Is there something I'm missing, or is this just a "gap" in the syntax?

JDB
  • 25,172
  • 5
  • 72
  • 123

2 Answers2

14

You could just add another same property without destructuring.

var record = { name: "foo", metadata: { createdDate: "2017-02-19",  lastModifiedDate: "2018-07-24", type: "bar" } };

let { metadata: { createdDate }, metadata } = record;
//    ^^^^^^^^                                        for nested destructuring
//                               ^^^^^^^^             for the value

console.log(metadata);
console.log(createdDate);
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
1

It depends on whether or not you want the nested object to also contain the destructured properties.

If you do then then see Nina Scholz's answer

If you don't then the use the ...rest syntax like so:

let {
    metadata: {
      createdDate,
      ...metadataExceptForCreatedDate
  }
} = record;
Aluan Haddad
  • 29,886
  • 8
  • 72
  • 84