How to use the Optional chaining operator(?.) in JavaScript

How to use the Optional chaining operator(?.) in JavaScript

·

3 min read

The optional chaining operator ?. is used to access the properties and methods of an object safely. If any of the intermediate properties in the chain is null or undefined, it stops evaluating the expression and returns undefined , rather than throwing an error.

What problem does it solve?

We often have an error that says TypeError: Cannot read properties of undefined when we access the properties of an object that is null or undefined.

Example:

const user = {
    name: "Peter"
};
console.log(user.address.country);// TypeError: Cannot read properties of undefined

In the above example, the user object doesn't have an address property. The value of the address property is undefined, and we are accessing the country property on undefined. So, the compiler throws the error TypeError: Cannot read properties of undefined .

A traditional way to handle this type of error is to use a conditional check:

// we only access country property if address property exists on user object
if(user && user.address){
    console.log(user.address.country);
}

But this solution becomes verbose when an object has many levels of nesting:

const user = {
    name:"Peter",
    address: {
        country:{
            name: "US",
            countryCode: "+1"
        }
    }
}

if(user && user.address && user.address.country){
    console.log(user.address.country.countryCode);
}

We can see in the above example that our code looks verbose and complex.

Use ?. to avoid complex conditional check

The optional chaining operator ?. makes our code easy to read and less verbose.

We don't have to check whether a property exists on an object. As soon as the optional operator (?.) encounter an undefined or null in chaining, it stops immediately and returns undefined .

const user = {
    name: "Peter"
};
// if user exists, then access address, if address exists, then access country
console.log(user?.address?.country);// undefined

We can see that we don't have to conditionally check if the address property exists on the user object.

The expression user?.address?.country can be read as: if the user exists then access address property, and if the address property exists then access country property.

Even if the object has many nested levels, our code looks easy to read and less verbose.

const user = {
    name:"Peter",
    address: {
        country:{
            name: "US",
            countryCode: "+1"
        }
    }
}
// less verbose and easy to read
console.log(user?.address?.country?.countryCode); // "+1"

Optional chaining is not valid on the left-hand side of an assignment

The optional chaining parameter(?.) can't be used on the left side of an assignment, it will throw an error Uncaught SyntaxError.

let user = {};
user?.name = "Peter";// Uncaught SyntaxError: Invalid left-hand side in assignment

Optional chaining with function calls

We can also check whether a method exists on an object.

const user = {
    getName(){
        console.log("Peter");
    }
}

user.getName?.(); // Peter
user.getAge?.(); // undefined

Optional chaining with an array

let arr;
console.log(arr[2]);//Error:Cannot read properties of undefined
console.log(arr?.[2]);// undefined

Conclusion

The optional chaining operator makes our code more readable and less verbose. And it also prevents throwing the error TypeError: Cannot read properties of undefined .

I hope you get to learn something from this blog. Thanks for reading the article.