Optional chaining in JavaScript
The optional chaining operator ?.
is for optional property access. Optional chaining allows us to write code that will immediately stop running some expressions if a null
or undefined
is found.
The optional chaining operator ?.
is available in TypeScript as of version 3.7.
Cannot read property of undefined
Consider the following example demonstrating object property access on an undefined
object.
let user;
const name = user.firstName;
This code will throw a JavaScript error that will say "Cannot read property 'firstName' of undefined." Since user
is undefined
, no properties can be accessed from the user
object. The optional chaining operator helps us to avoid this error during object property access.
Optional chaining to the rescue
Let's re-visit this same example, but this time with the optional chaining operator.
const name = user?.firstName;
When user
is defined, user?.firstName
will be computed and firstName
will be accessed from the user
object. However, when user
is null
or undefined
, the optional chaining operator will stop execution and just return undefined
as the name
.
const user = undefined;
const name = user?.firstName;
console.log(name); // undefined
const user = { firstName: 'John', lastName: 'Smith' };
const name = user?.firstName;
console.log(name); // John
How optional chaining works
Consider the following example to see the same line of code with and without the optional chaining operator to gain a better understanding of how it works.
// with optional chaining
const name = user?.firstName;
// without optional chaining
const name = (user === null || user === undefined) ? undefined : user.firstName;
Left side checks only
The optional chaining operator will only check if the value on the left of it is null
or undefined
. It will not check any properties to the right of it.
const user = {};
const zip = user?.address.zip;
console.log(zip);
This code block throws an error saying "Cannot read property 'zip' of undefined." This is because there is no address
property in the user
object. Thus, it is undefined
and a zip
property cannot be accessed from undefined
. The optional chaining operator only helped us with null
and undefined
checks on the user
object appearing to the left of it.
Nested object property access
The optional chaining operator can be used several nested levels deep.
const user = {};
const zip = user?.address?.zip;
console.log(zip); // undefined
This example will not throw the error we saw in the previous example because we have added the optional chaining operator to the address
property. If address
is found to be null
or undefined
, then undefined
is returned without throwing an error.