Uncategorized

Destructuring in javascript

ES6 introduced a new feature called destructuring. To better understand it let’s look into the basics of javascript objects.To add single property to an object we use a dot notation.

var user = {};
user.name = 'John doe'
user.age = '25'

By the nature of dot notation we can add properties one at a time. To extract property we need to use the same syntax . If we want to add multiple properties to an object we need to use object literal notation during time of initialisation

var user = {
    name : 'John doe',
    age: '25'
}

We have a way to add multiple properties at a time but we do not have a way to exact multiple properties at a time until destructuring was introduced in es6 .

So as object literals allows us to add multiple properties in an object, destructuring allows us to extract multiple properties from an object. This reduces the amount of code we have to write dramatically using destructuring

var user = {
    name: 'john doe',
    age: '25',
    email: 'johndoe@gmail.com'
}

Before destructuring

var name = user.name //prints john doe
var age = user.age //prints 25
var email = user.email //prints johndeo@gmail.com

Using destructuring

var {name, age, email} = user;

They both create and initialise 3 variables name, age and email.

Another feature of destructuring is that we can destructure the result of function invocation

function getUser() {
    return {
        name: 'john doe',
        age: '25',
        email: 'johndoe@gmail.com'
    };
}

Rather than invoking “getUser” and grabbing all the properties off it one by one we could use destructuring

var {name, age, email} = getUser();
 
name //prints john doe
age //prints 25
email //prints johndoe@gmail.com

Why is destructuring important?

It provides a quicker and neater way to assign values: 

Consider a scenario where we have data of stores in an object to be shown on a map. 

const result = {
    responseType: 'discounts',
    id: '10533019bf4938538cef383481538a4b',
    locations: {
        city: 'UNION CITY',
        distance: 4.521417621024534,
        lat: 40.77651180000001,
        lng: -74.0255827,
        state: 'NJ',
        street: '4012 BERGENLINE AVE',
        url: '/benefits-discounts/',
        zip: '07087',
        catCode: 10004
    }
};
 
function displayMarkersOnMap(result) {
    console.log('Type of response,' + result.responseType);  // Type of response discounts
    console.log('latitude ' + (result.locations.lat)); // latitude 40.77651180000001
    console.log('longitude ' + (result.locations.lng)); // longitude -74.0255827
    console.log('cityname' + (result.locations.city)); //cityname UNION CITY
}
 
displayMarkersOnMap (result);

We can achieve the result from above code but there are a few cautions to be taken care of – we can easily make a typo , instead of writing locations we can write location which will give undefined and again if the object is deeply nested, the chain to access the inner values become longer and more code has to be written which makes the coding complex and expensive. With destructuring we can shorten the code, make it less complex and more readable. 

function displayMarkersOnMap({ responseType, locations: { lat = 0, lng = 0, city = 0 } }) {
    console.log('Type of response' + responseType);
    console.log('latitude ' + lat);
    console.log('longitude' + lng);
    console.log('cityname' + city);
}
 
displayMarkersOnMap(result);

Another Example:

We often use axios to do a HTTP request to get data from services. It returns the following object: 

{
    data : {},
    status:200,
    statusText: 'OK',
    headers:{},
    configs:{},
    requests:{}
}

Data gives us the response provided by the server. Consider a scenario where we need to get data of all the users we would use axios  

const request = await axios.get('getuser/user');

Request object will have the same structure as shown above . To get the data provided by the server we would get request.data. Suppose we want to get data for a particular user with an id= 1730 which needs to be passed in the request getuser/user/:userId and it returns an array .To extract data we can do request.data[0]

We can also use destructuring here :

const { data } = await axios.get('getuser/user')
 
console.log(data); // [{username: 'john doe'}]

How to destructure properly? 

Suppose we have an object 

const person = {
    name: 'John Doe'
}

Destructuring it –

const { name } = person || {}

We need to add or empty object {} because destructuring throws error if the value is undefined or null as we shown in example : 

let name = undefined;
const { personName } = name;

This will throw an error –

Uncaught TypeError: Cannot destructure property ‘personName’ of ‘name’ as it is undefined.

But if we set it to an empty object

name = undefined || {}
const { personName } = name //it gives undefined

Another example:

const object = {
    name: {
        details: {
            title: 'john doe',
            description: 'loreum ipsam loreum oupsim'
        }
    }
}
const { name: { details: { title } } } = object || {}

Name is within object, details is within name and finally title is destructured from details. We are assigning a variable named title for title. This works untill all the properties in the object exists and none of them are undefined or null. We can deal with undefined by setting defaults value.

const personDetails = {
    name: 'John doe',
}
const { name = 'defaultName', age = 21 } = personDetails;
  
console.log(name); // John doe
console.log(age); //21

Providing default values using destructuring works if variable is either undefined or doesn’t exist.  All other values like null, false, 0 are not dealt by setting default values.

const personDetails = { name: undefined } 
const { name = 'John doe'} = personDetails;
console.log(name) // John doe

while for null: 

const personDetails = { name: null } 
 
const { name = 'John doe'} = personDetails;
console.log(name) //null

ARRAY DESTRUCTURING

var user = ['john doe','john@gmail.com','hyderabad']

To identify each item in the array we need to create variable  for each item

let name = user[0],
    email = user[1],
    place = user[2];

This can be tedious. Using destructuring we can more effectively extract items from the array

var [name, email, place] = user;

PRACTICAL USES OF DESTRUCTURING IN JAVASCRIPT

1. Nested array and Objects

let user = {
    level : 'associate',
    paid: true,
    professionalDetails: {
        id: 123455,
        level: 2
        personalDetails : {
            name : 'john',
            age : 25,
            gender: male
        }
    }
}
let name = user.professionalDetails.personalDetails.name,
    age = user.professionalDetails.personalDetails.age,
    gender = user.professionalDetails.personalDetails.gender;
 
//We can also save user.professionalDetails.personalDetails in a variable 
 
let details = user.ProfessionalDetails.PersonalDetails;
let name = details.name,
    age = details.age,
    gender = details.gender

Still this will be a lot of work. To simply it we can use destructuring –

let {name, age, gender} = user.professionalDetails.personalDetails

Using this name prints john , age prints 25 and gender prints male.

Destructuring helps to break complex code into simpler code. It makes the code less complex and cleaner.

2.Naming functional arguments 

Suppose we have a function which accepts multiple parameters

getFilterData = (userType, category, publishedDate, language, author) => {
 
}

Whenever another developer uses this function he has to take care of 2 things – the order in which arguments are passed  and read documentation to filter out the arguments he doesn’t need.

getFilterData('active-user','category1','05-07','English','john');

For simplifying it we can pass parameters as Objects and use destructuring so that we don’t need to worry about the order of the parameters and ignore the arguments we do not want.

//option1
getFilterData = ({userType, category, publishedDate, language, author}) => {
}
 
//option2
getFilterData({
    category:'category1',
    language:'English',
    userType:'active-member',
    publishedDate:'05-07',
    author:'John'
});

Even if the order in which the parameters are sent are not the same, the function will know which parameter is associated with which value.We can also ignore the arguments we don’t want into consideration

getFilterData({
    userType:'active-member',
    publishedDate:'05-07',
    author:'John'
});

CONCLUSION – Destructuring simplifies the code complexity and makes the code cleaner and readable. It works great with complex functions which have a lot of parameters and default states. Destructuring makes it easier to read and use the code as it breaks down the complex object . It also increases performance as we use variables and use them multiple times.

 

About The Author