DEV Community

Cover image for Optional chaining '?.' in JavaScript 💪🔥
Insha Ramin
Insha Ramin

Posted on • Updated on

Optional chaining '?.' in JavaScript 💪🔥

Hey Readers 👋

In this article, we’ll learn about the optional chaining (?.) that simplifies the way to access values through nested objects.

What the heck is Optional chaining? 🥴

The optional chaining ?. is a recent addition to the language which is a secure way to access nested object properties, even if an intermediate property doesn’t exist.

With the optional chaining if a certain property doesn't exist then undefined is returned immediately.

The optional chaining ?. syntax has three forms:

  • obj?.prop – returns obj.prop if obj exists, otherwise undefined.

  • obj?.[prop] – returns obj[prop] if obj exists, otherwise undefined.

  • obj.method?.() – calls obj.method() if obj.method exists, otherwise returns undefined

To understand the concept better let's have a look at a few of the use cases.

  • Let's see what happens if we try to access a property that doesn't exist without the use of optional chaining.
console.log(restaurant.closingHours.mon.close)
Enter fullscreen mode Exit fullscreen mode

We get an error. That’s the expected result. JavaScript works like this. As restaurant.closingHours is undefined, an attempt to get restaurant.closingHours.mon.close fails with an error.

  • In order to avoid this error, we first need to check if this property exists. The obvious solution would be to check the value using if or the conditional operator ?, before accessing its property.
if(restaurant.closingHours && restaurant.closingHours.mon)
console.log(restaurant.closingHours.mon.close);
Enter fullscreen mode Exit fullscreen mode

It works, there’s no error. But it makes our code more unreadable and messier. It gets more offended pretty quickly when we have a deeply nested object with lots of optional properties.

  • Now, let's attempt to access the property by using optional chaining.
console.log(restaurant.closingHours.mon?.close); //undefined
Enter fullscreen mode Exit fullscreen mode

We see the code is short and clean, there’s no duplication at all.

Note: Only if the property that is before ?. that's mon here exists then this close property will be read and if not then immediately undefined will be returned.

In other words, the ?. checks the left part for null/undefined and allows the evaluation to proceed if it’s not so.

Something “exists” here means if it’s not null and not undefined.

  • Let's see one more example:
let nestedProp = user.first?.last;

Enter fullscreen mode Exit fullscreen mode

By using the ?. operator instead of just ., JavaScript knows to implicitly check to be sure user.first is not null or undefined before attempting to access user.first.last. If user.first is null or undefined, the expression automatically short-circuits, returning undefined.

Combining with the nullish coalescing operator

In a nutshell, the nullish coalescing operator, written as ?? is a logical operator that returns its right-hand side operand when its left-hand side operand is null or undefined, and otherwise returns its left-hand side operand.

We can set a default value if our optional chaining returns something unwanted.

let user = {
  name: "Insha",
  details: { age: 19 }
};
const userCity = user?.city ?? "Unknown city";
console.log(userCity); // Unknown city

Enter fullscreen mode Exit fullscreen mode

Since the city property is not provided and evaluates to the
undefined

courtesy of the optional chaining operator, the nullish coalescing operator then kicks in and defaults to the right-hand side operand "Unknown city" because the left-hand side operand is evaluated to undefined.

Optional chaining on the left-hand side of an assignment

Optional chaining is invalid when used on the left-hand side of an assignment. This results in an error.

let user = {};
user?.name = Insha; //  SyntaxError
Enter fullscreen mode Exit fullscreen mode

Optional chaining with function calls

We can use optional chaining when attempting to call a method that may not exist.

For example,
?.()

is used to call a function that may not exist.

Using optional chaining with function calls causes the expression to automatically return undefined instead of throwing an exception if the method isn't found:

let userAdmin = {
  admin() {
    alert("I am admin");
  }
};

let userGuest = {};

userAdmin.admin?.(); // I am admin

userGuest.admin?.(); // nothing (no such method)

Enter fullscreen mode Exit fullscreen mode

The
?.[]

syntax also works, if we’d like to use brackets [] to access properties instead of dot .

Optional chaining can be used often when we are fetching responses from an API. We may not be 100% sure if a certain object exists in our API response. With optional chaining, we can check to see if something exists and handle an error gracefully.

Wrapping Up!

Optional chaining in JavaScript is very useful - we can access values without checking if the parent object exists. Instead of returning an error, it will return null or undefined.

Also if you got any questions feel free to ping me on Twitter

Top comments (0)