Javascript Optional Chaining Operator (?.)
The Optional Chaining Operator (?.
) is a JavaScript operator that lets you access properties of a object without doing explicit checks
(using an if
statement, or a ternary operator (condition ? expr1 : expr2
), for example) on the existence of the object itself.
And that's amazing, mainly because it's quite common to have several objects chained together, where some of them may be null
or undefined
in some application state.
The problem
Let's see a very simple example:
Imagine that, in some state of my application, we'll have an object user that will have another chained object called contact that will have some contact properties:
const user = {contact: {phone: '(000) 000-0000'}};
But let's assume this contact data is not available in an initial state, so my user object will be empty:
const user = {};
With just what we have here, we can't know what state our application is in. Therefore, we will not be able to know if the contact object exists in the user object. So... What happens if we try to access the properties of the contact object in different states?
Well, if the contact object is on user as expected, then it'll work correctly:
const user = {contact: {phone: '(000) 000-0000'}};console.log('Phone:', user.contact.phone);// ✅ Works!
But if the contact object is not yet in the user object, then:
const user = {};console.log('Phone:', user.contact.phone);// ❌ Uncaught TypeError:// Cannot read properties of undefined (reading 'phone')
The contact object hasn't been defined in the user object yet, so we can't access its properties.
Using the optional chain operator
As already said, there are several ways to solve this, but the optional chaining operator keeps everything very clean and simple:
console.log('Phone:', user.contact?.phone);// here ^
- If
user.contact
exists, then we will be able to access thephone
property and display it. - If
user.contact
isnull
orundefined
, then the optional chaining operator will returnundefined
and will not even attempt to access thephone
property.
Possibilities
In addition to chained objects, we can use the operator in functions, and even in arrays:
Functions:
const photo = user.viewPhoto?.();It will only run the displayPhoto function if it isn't
null
orundefined
. Otherwise, photo will beundefined
.Arrays:
const user = {contacts: [{ phone: '(000) 000-0000' }, { phone: '(111) 111-1111' }]};const firstPhone = user.contacts?.[0]?.phone;Here we can see two possibilities:
- In
contacts?.
, we check if the contacts array already exists in the user object, before proceeding to access the rest of the chain (which, in this case, is trying to access the first element of the array). - If
contacts?.
returned the array (instead ofundefined
), as expected, then we go ahead and check if the first element exists:[0]?.
. - If we have gone through both optional chaining operators, then we are able to access the phone property.
If not, we'll have
undefined
as the value of the constant firstPhone.
- In
TL;DR:
(Portuguese only) You can see a summary of this post on Reels at my tiktok account or my instagram account: