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?
Summary. JavaScript destructuring, nested and otherwise, is a nice shorthand to allow us to quickly define variables from values in a collection, object, or array. We can use it with rest syntax to assign remaining elements a variable. We can rename the elements that we pull out to a variable name of our choosing.
It looks like destructuring feature works by reference and it's not copying the value. So when you work with destructuring bear in mind to pay a lot of attention when you change a value inside your destructured Objects and Arrays!
To destructure an array in JavaScript, we use the square brackets [] to store the variable name which will be assigned to the name of the array storing the element.
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);
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;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With