DEV Community ๐Ÿ‘ฉโ€๐Ÿ’ป๐Ÿ‘จโ€๐Ÿ’ป

DEV Community ๐Ÿ‘ฉโ€๐Ÿ’ป๐Ÿ‘จโ€๐Ÿ’ป is a community of 970,177 amazing developers

We're a place where coders share, stay up-to-date and grow their careers.

Create account Log in
Cover image for โ›“ The optional chaining operator in JavaScript
Chetan
Chetan

Posted on

โ›“ The optional chaining operator in JavaScript

Definition

The optional chaining operator ?. permits reading the value of a property located deep within a chain of connected objects.

The optional chaining was introduced as part of the ES2020 standard.

Why this ?

It changes the way we access the properties from the deep objects. The optional chaining makes your code look cleaner ๐Ÿงผ and crisp ๐Ÿ”ฅ

Consider this piece of code, where the data object has a query and an answer to the query.

const response = {
    "data": {
        "query": "What is javascript ?",
        "answer" : {
            "value": "JavaScript is ๐Ÿ’›"
        }
    }
}

To access the value, you have to write a loooong conditional statement which is difficult to read and format ๐Ÿ˜ข

let theValue;

if(response &&
response.data &&
response.data.answer &&
response.data.answer.value) {
    theValue = response.data.answer.value;
} else {
    theValue = 'JavaScript is BAE ๐Ÿ’›โค๏ธ';
}

But with optional chaining, you can access the value easily ๐Ÿ˜ƒ and you don't have to worry about the null & undefined checks.

response?.data?.answer?.value

// Output
JavaScript is ๐Ÿ’›

Wow, this code looks so clean ๐Ÿงผ and crisp !! If the value is not present, we can assign a default value to it.

response?.data?.answer?.key || 'JavaScript is BAE ๐Ÿ’›โค๏ธ'

// Output
JavaScript is BAE ๐Ÿ’›โค๏ธ

Setting up the Babel Plugin

Babel 7.8.0 supports the new ECMAScript 2020 features by default. There is no need of enabling an individual plugin for optional chaining (?.).

If you are using the latest Babel version which is above or equal to 7.8.0, then it's an easy setup

npm install --save-dev @babel/cli @babel/core @babel/preset-env

Now add the following configuration to the .babelrc

{
    "presets": [
        "@babel/preset-env"
    ]
}

The necessary babel modules and the preset configurations are done. Now it's time to do the babel magic โœจ

Run this command to transpile the code to the supported version everywhere. This command will work if you have installed the babel module globally.

babel app.js --out-file script-transpiled.js

All the optional chaining code should be placed in app.js and then the above command should be executed. This produces the transpiled code which works in major browsers and in node.js.

Different types of optional chaining

1. Optional chaining with function calls

Optional chaining can be used when you are trying to invoke a method which may not exist. Using optional chaining with function calls causes the expression to automatically return undefined instead of throwing an exception.

class Operation {
  constructor(a, b) {
    this.a = a
    this.b = b
  }

  getSum() {
    return this.a + this.b
  }
}

let o = new Operation(2, 3);
o.getSum(); // 5

o.getDiff(); // Output - Uncaught TypeError: o.getDiff is not a function

// Check if the function exists
typeof o.getDiff != "undefined" && o.getDiff(); 

// With the use of optional chaining
o.getDiff?.() // Output - undefined

2. Optional chaining with expression

If the left operand is null or undefined, the expression after the optional chaining operator will not be evaluated.

let user = null;
let age = 12;
let isTeenage = user?.[value++];
console.log('isTeenage :: ', isTeenage);

//Output

isTeenage :: undefined

The user is defined as null, while executing the line #3, the isTeenage didn't throw any error because if the left operand is null or undefined, the expression will not be evaluated.

3. Combining with the nullish coalescing operator [which is another ES2020 feature]

let user = null;
let age = 12;
let isTeenage = user?.[value++] ?? 'not a teenager !!';
console.log('isTeenage :: ', isTeenage);

// Output

isTeenage :: not a teenager !!

Things about optional chaining

๐Ÿš€ Clean & Readable code
๐Ÿš€ Don't worry about null or undefined in an object
๐Ÿš€ Less error

Browser Support

  • Chrome - 80
  • Edge - 80
  • Firefox - 74
  • Internet Explorer - NO
  • Opera - 67
  • Node.js - 14.0.0

References

Top comments (1)

Collapse
 
frankfont profile image
Frank Font

Cool now I want to upgrade to nodejs v14. Maybe I will in a few months just because of this operator. I like it

In defense of the modern web

I expect I'll annoy everyone with this post: the anti-JavaScript crusaders, justly aghast at how much of the stuff we slather onto modern websites; the people arguing the web is a broken platform for interactive applications anyway and we should start over;

React users; the old guard with their artisanal JS and hand authored HTML; and Tom MacWright, someone I've admired from afar since I first became aware of his work on Mapbox many years ago. But I guess that's the price of having opinions.