Javascript Optional Chaining Operator

Introduction

Learning the optional chaining syntax allows us to safely access properties of nested objects without causing errors, even if those properties do not exist.

The Problem of “Non-existent Properties”

Accessing object properties is a very intuitive task that developers do every day. However, when the source of data is unstable, such as when using data from third-party sources or user input, how can we avoid errors caused by using non-existent values?

const person = {
name: 'Doe',
age: 28,
};
console.log(person.child.age); // Uncaught TypeError: person.child is undefined

We can use the conditional operator🔗 or the logical operator🔗 to achieve this:

// If person.name exists, use person.name, otherwise it equals undefined.
console.log(person.name ? person.name : undefined);
// If person exists, get person.name, otherwise it equals undefined
console.log(person && person.name);

Although this works, it is not a very elegant solution, and as the level of nesting increases, the code becomes more cumbersome.

const person = {};
console.log(person.address ? (user.address.street ? user.address.street.name : null) : null);

Using Optional Chaining .?

The solution to the above problem is simple: use optional chaining🔗. In short, if the input value does not exist or is null, the selected value will be treated as undefined, preventing the program from crashing. There are two usages:

  1. Avoid crashing the program due to accessing non-existent values (if the value does not exist, it gets undefined)
  2. Set default values (in conjunction with the ?? operator)
const person = {};
// Gets undefined
console.log(person?.name);
// Gets default value "Unnamed User"
console.log(person?.name ?? 'Unnamed User');

This is typically used when accessing remote data or the DOM. If you are very sure that the data you are retrieving will definitely exist, you can omit it; including it adds an extra layer of exception protection.

Additionally, “chaining” optional chaining is also possible, as shown below:

let user = {};
// Gets undefined
console.log(user?.address?.street);

Notes

You should not overuse ?. optional chaining; use it only for non-essential data selection. For example, when the address in the user object is non-essential, you can use user.address?.street to select it, rather than user?.address?.street.

Excessive use of optional chaining can lead to inappropriate timing warnings being suppressed, causing variables to be filled with undefined values, making debugging more difficult.

References