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)
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.
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.if(restaurant.closingHours && restaurant.closingHours.mon) console.log(restaurant.closingHours.mon.close);
- Now, let's attempt to access the property by using optional chaining.
console.log(restaurant.closingHours.mon?.close); //undefined
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.firstName?.lastName;
By using the ?.
operator instead of just .
, JavaScript knows to implicitly check to be sure user.firstName is not null or undefined before attempting to access user.firstName.lastName. If user.firstName 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
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
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)
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