Nested Object Destructuring in JavaScript

We’re going to talk about something you should definitely know about as a JavaScript developer that was first introduced in ES6 called the Destructuring Assignment. Just keep in mind that it’s not supported in all browsers yet (I’m looking at you, Internet Explorer), so there’s a chance it might not work in your browser.

To explain why, I’m going to show you a real-life example of a time when nested object destructuring would make things compact and easier to use.

Imagine we have a rudimentary application that allows users to log in and keep track of their finances and monthly payments towards bills. The user’s information is stored in an object and in this case, our pretend user, Joe, has only paid two of his three bills this month (mortgage and car) and we want to show that to him. Our code could look something like this:

const user = {
name: 'Joe',
age: 25,
bills: {
mortgage: 1000,
car: 250,
phone: 0
}
}
function showBillsPaid(user) {
console.log('Hello, '+ user.name)
console.log('Your mortgage payment was: $' + user.bills.mortgage)
console.log('Your car payment was: $' + user.bills.car)
console.log('Your phone payment was: $' + user.bills.phone)
}
showBillsPaid(user)// Hello, Joe
// Your mortgage payment was: $1000
// Your car payment was: $250
// Your phone payment was: $0

While we would definitely achieve our goal with the code above, the end result is sloppy and you could potentially make a typo. Plus, this type of coding doesn’t scale well. What if you want to offer custom payment types, two payments are made in the same month and you need to keep track of them in an array, or if your user wants to keep track of bi-monthly paychecks being deposited into their account?

There’s lots of different scenarios and ‘what-if’s’, especially with money, and despite utilities and bills being generally predictable, we, as software engineers, have to make our programs flexible in order to be inclusive to everyone.

This is where nested destructuring comes in!

Let’s rewrite the code snippet from before so we can see how nested object destructuring works.

const user = {
name: 'Joe',
age: 25,
bills: {
mortgage: 1000,
car: 250,
phone: 0
}
}
function showBillsPaid({name, bills: {mortgage, car, phone}}) {
console.log('Hello, '+ name)
console.log('Your mortgage payment was: $' + mortgage)
console.log('Your car payment was: $' + car)
console.log('Your phone payment was: $' + phone)
}
showBillsPaid(user)// Hello, Joe
// Your mortgage payment was: $1000
// Your car payment was: $250
// Your phone payment was: $0

Just like in regular object destructuring, we’re defining name as a variable, but instead of defining bills too, we’re using nested object destructuring to define mortgage, car, and phone as variables too.

Note: Don’t use empty nested object literals while nested destructuring. While it may be valid syntax, it actually does no assignment. For example:

// this doesn't work!const { bills: {} } = user

What if our user didn’t fill out his name when making his profile? Our code says hello to the user by name and we don’t want to change that. There’s actually a really easy way to fix this by using default values.

const user = {
age: 25,
bills: {
mortgage: 1000,
car: 250,
phone: 0
}
}
function showBillsPaid({name = 'User', bills: {mortgage, car, phone}}) {
console.log('Hello, '+ name)
console.log('Your mortgage payment was: $' + mortgage)
console.log('Your car payment was: $' + car)
console.log('Your phone payment was: $' + phone)
}
showBillsPaid(user)// Hello, User
// Your mortgage payment was: $1000
// Your car payment was: $250
// Your phone payment was: $0

We specified a default value of ‘User’ for the name in case it hadn’t been specified yet on the user object. We could also add a new feature to our app that allows Joe to click a button to pay off all of his bills automatically with his pre-set default payment amounts!

const user = {
name: 'Joe',
age: 25,
bills: {}
}
function showBillsPaid({name = 'User', bills: {mortgage = 1000, car = 250, phone = 0}}) {
console.log('Hello, '+ name)
console.log('Your mortgage payment was: $' + mortgage)
console.log('Your car payment was: $' + car)
console.log('Your phone payment was: $' + phone)
}
showBillsPaid(user)// Hello, Joe
// Your mortgage payment was: $1000
// Your car payment was: $250
// Your phone payment was: $0

Even though it might seem a bit complicated, we always want to think of bigger and better ways to be RESTful while maintaining a great user experience and I think that destructuring is one way to do that!

Full-Stack Engineer, UX/UI Aficionado, and lover of coffee.