codewithjohn.dev
Published on

JavaScript Optional Chaining

Table of Contents

The execution of your code may be interrupted by errors that result from intermediary properties that are frequently null or undefined. The innovative optional chaining operator (?.) was added by JavaScript in ECMAScript 2020 (ES2020) to address this issue. With the confidence that this operator gives you, you can code with greater ease and stability.

The Problem Without Optional Chaining

Before we start exploring let's consider a common scenario where nested property access can lead to errors:

Consider the following JavaScript object representing a user with nested address information:

const user = {
  name: 'John',
  address: {
    city: 'New York',
    zipcode: '10001',
  },
}

The traditional approach to access the city involves multiple checks to ensure that the properties exist and are not null or undefined:

let city
if (user && user.address && user.address.city) {
  city = user.address.city
} else {
  city = 'Unknown'
}
console.log('Traditional Approach:', city) // Output: New York

This code checks if the user object exists, if it has an address property, and if the address property has a city property. If any of these conditions fail, the city variable is set to “Unknown.” this is the kind of problem Optional Chaining solves

Understanding Optional Chaining

Optional chaining (?.) is your hero in JavaScript when dealing with nested objects that might have missing properties (null or undefined). It lets you access properties gracefully, preventing errors and keeping your code clean.

Here's how it works:

object?.property1?.property2?.method()
  • Start with an object (object).
  • Use ?. to access properties (property1, property2).
  • Call methods (method()).
  • If any part is null/undefined, evaluation stops, returning undefined (no errors!).

With optional chaining, accessing the nested city property from the above becomes much simpler:

const city = user?.address?.city || 'Unknown'
console.log('Optional Chaining Approach:', city) // Output: New York

The ?. operator is used to access the city property of the user’s address. If any intermediate property (user or address) is null or undefined, the expression short-circuits, and the result is immediately set to “Unknown.”

How to Call Nested Methods

In addition to accessing properties, optional chaining also works with nested methods. Let’s consider a user object with a method getAddress() that returns the user’s address:

const user = {
  name: 'Alice',
  getAddress() {
    return {
      city: 'Los Angeles',
      zipcode: '90001',
    }
  },
}

Traditionally, calling the getAddress() method involves similar checks:

let city
if (user && user.getAddress && typeof user.getAddress === 'function') {
  const address = user.getAddress()
  if (address && address.city) {
    city = address.city
  } else {
    city = 'Unknown'
  }
} else {
  city = 'Unknown'
}
console.log('Traditional Method Call:', city) // Output: Los Angeles

Using optional chaining, we can simplify the method call:

const city = user?.getAddress?.()?.city || 'Unknown'
console.log('Optional Chaining Method Call:', city) // Output: Los Angeles

Optional Chaining Arrays

Consider the following code snippet

const arr = [1, 2, 3, 4, 5]

// Using logical AND operator
const firstElement = arr && arr[4]
console.log(firstElement) // Output: 5

This code checks that arr is truthy before attempting to access the element at the forth index. However, we can simplify this using the optional chaining operator

const arr = [1, 2, 3, 4, 5]

// Using optional chaining operator
const firstElement = arr?.[4]
console.log(firstElement) // Output: 5

Conclusion

With ES2020, optional chaining (?.) was added as a potent technique to the JavaScript toolkit. It makes it easier to access nested object and array properties and methods, especially when working with possibly null or undefined data. Optional chaining improves code readability and maintainability and lowers error risk by doing away with the requirement for frequent null checks. Use optional chaining to build more readable code.