How to destructure an array of objects or any mix of objects and arrays in JavaScript?

Learn JS: Destructuring, Lesson 7.

Destructuring an array of objects #

Let's start with a simple array:

const users = [
{
name: "robot",
age: 10
}, {
name: "person",
age: 34
}, {
name: "dog",
age: 2
}
]

Destructuring object at a given index #

In practice, when I had to access the object in the array, it's usually the first one (at the index 0). Let's see how that looks like without destructuring.

(If you want to learn how to destructure any other index then take a look at How to destructure arrays in JavaScript?)

const name = users[0].name;
const age = users[0].age;
console.log(name, age)
// "robot" 10

If it gets more complicated, it makes sense to store the first element in a new variable.

const firstUser = users[0];
const name = firstUser.name;
const age = firstUser.age;
console.log(name, age)
// "robot" 10

1. Now let's introduce destructuring one step at a time. #

First, let's get the object from the array.

const [firstUser] = users;
const name = firstUser.name;
const age = firstUser.age;
console.log(name, age)
// "robot" 10

2. Let's destructure the object as well. #

const [firstUser] = users;
const {name, age} = firstUser;
console.log(name, age)
// "robot" 10

3. The last step is to destructure the element in place. #

const [{name, age}] = users;
console.log(name, age)
// "robot" 10

Destructuring objects in an array #

const adminUsers = [
{
reallyLongExampleProperty: "foo",
anotherLongPropertyName: 10
}, {
reallyLongExampleProperty: "bar",
anotherLongPropertyName: 34
}
]

adminUsers.forEach((admin) => {
console.log(`${admin.reallyLongExampleProperty} ${admin.anotherLongPropertyName}`)
});
// So in practice what you do is:
adminUsers.forEach((admin) => {
const reallyLongExampleProperty = admin.reallyLongExampleProperty;
const anotherLongPropertyName = admin.anotherLongPropertyName;

console.log(`${reallyLongExampleProperty} ${anotherLongPropertyName}`)
});

Obviously you could destructure such an example inside the function:

adminUsers.forEach((admin) => {
const {reallyLongExampleProperty, anotherLongPropertyName} = admin;
console.log(`${reallyLongExampleProperty} ${anotherLongPropertyName}`)
});

But you can destructure the object right in the argument of the function.

adminUsers.forEach(({reallyLongExampleProperty, anotherLongPropertyName}) => {
console.log(`${reallyLongExampleProperty} ${anotherLongPropertyName}`)
});

Destructing an array inside an object #

Let's try getting the first element from the array. Let's say we want to get the first line (index 0) of the document to give the user more context on what it's about:

const document = {
title: "Title to be shown",
lines: [
"first line",
"second line",
"third line."
]
}
const firstLine = document.lines[0];
console.log(firstLine)
// "first line"

So now it's time to use destructuring:

const {lines: [firstLine]} = document;
console.log(firstLine)
// "first line"

Please notice that in this particular case code looks more complicated. So while it's technically possible to destructure even in such simple situations, the old way can look much cleaner and be easier to understand.

Destructuring a deeply nested mix of arrays and objects #

Let's try to complicate the previous example a little.

const book = {
title: "Title to be shown",
authors: [{
name: "Kris"
}, {
name: "Editor"
}],
lines: [
"first line",
"second line",
"third line"
]
}
const title = book.title;
const authorName = book.authors[0].name;
const firstLine = book.lines[0];
console.log(title, authorName, firstLine)
// "Title to be shown" "Kris" "first line"

1. Destructuring the title. #

const {title} = book;

2. Destructuring the authorName. #

const {authors: [{name: authorName}]} = book;

3. Destructuring the firstLine. #

const {lines: [firstLine]} = book;

4. Putting it all together. #

const {
title,
authors: [{name: authorName}],
lines: [firstLine]
} = book;
console.log(title, authorName, firstLine)
// "Title to be shown" "Kris" "first line"

Unfortunately, this code is not necessarily cleaner and easier to understand.

Refactoring #

You can destructure deeply nested objects to the exact properties you want doesn't mean you always should. For example, the code is much easier to follow if we won't destructure the authorName and settle only with the firstAuthor variable.

const {
title,
authors: [firstAuthor],
lines: [firstLine]
} = book;
console.log(title, firstAuthor.name, firstLine)
// "Title to be shown" "Kris" "first line"

What I want to warn against is sacrificing clarity to improve overcomplicated code. For example, we could have sacrifice the clarity of authorName and use only name.

const {
title,
authors: [{name}],
lines: [firstLine]
} = book;
console.log(title, name, firstLine)
// "Title to be shown" "Kris" "first line"

It works the same way, but if the function got any longer, then it wouldn't be clear what name is. Most people would assume it's the name of the book, which can lead to bugs. You can argue that it's a silly example, but I've seen that happen in a much more complicated business code, and it's something I've learned to avoid.

(⬅ Visit the previous lesson to learn how to destructure arrays in JavaScript.



Share on Hacker News
Share on LinkedIn


← Home