• Home
  • JavaScript – Optional Chaining

JavaScript – Optional Chaining

As of August 2019, a new proposal optional chaining reached stage 3 and is going to be a nice improvement. Optional chaining changes the way properties are accessed from deep objects structures.

JavaScript language has added few exciting features over the past few years, like the spread operator, default argument values, and arrow functions and now new feature is optional chaining. Optional chaining allows developers to reference object properties which may or may not exist without trigger an error.

The optional chaining operator ?. permits reading the value of a property located deep within a chain of connected objects without having to expressly validate that each reference in the chain is valid. The ?. operator functions similarly to the . chaining operator, except that instead of causing an error if a reference is null or undefined, the expression short-circuits with a return value of undefined. When used with function calls, it returns undefined if the given function does not exist.

This results in shorter and simpler expressions when accessing chained properties when the possibility exists that a reference may be missing. It can also be helpful while exploring the content of an object when there’s no known guarantee as to which properties are required.

// API response object
const person = {
    details: {
        name: {
            firstName: "Kristijan",
            lastName: "Klepac",
        }
    },
    jobs: [
        "Senior Full Stack Web Developer",
        "iOLAP"
    ]
}
// Getting the firstName
const personFirstName = person.details.name.firstName;

In above example how we get firstName is prety bad because it’s hard to get persons name details. Look at the example bellow how you need to check if firstName exists if you don’t wan’t error to be thrown.

// Checking if firstName exists
if( person &&
    person.details &&
    person.details.name ) {
        const personFirstName = person.details.name.firstName || 'unknown';
}

Of course with Lodash you can simplify code above like this:

_.get(person, 'details.name.firstName', 'unknown');

But Lodash is then another dependency in your project.

Let’s see another solution with new optional chaining:

const personFirstName = person?.details?.name?.firstName;

Explanation: Here is how you have to think about it. If there is a ?. at the beginning of a property, it is as you would ask your self does person exists? ( has person the value null or undefined? ). If yes then I will not return an error but just undefined. So personFirstName will have the value of undefined. This question will repeat for details? and name?. If any of these values is ‘null’ or undefined, then personFirstName will also be undefined. This is called Short-circuiting. Once javascript finds a null or undefined it will short circuit and stop going deeper.

Example with Nullish coalescing operator:

const personFirstName = person?.details?.name?.firstName ?? 'unknown';

Babel to the rescue.The Nullish coalescing operator is represented as ??. It is also pretty easy to read. If the left side is undefined than personFirstName will get the value of the right side from ??.

Example with dynamic properties:

const jobNumber = 1;
const secondJob = person?.jobs?.[jobNumber] ?? 'none';

Example with function or method call:

const someJob = person?.jobs.getSomeJob?.() ?? 'none';

If method does not exist on that object, it will return undefined.

But … Right now no browser supports this out of the box — so we can use Babel. There is a babel.js plugin already that is pretty easy to integrate if you have already Babel setup.

babel-plugin-proposal-optional-chaining

Tags:

Copyright by Kristijan Klepač 2018