
Introduction
If you’ve been a JavaScript developer for any length of time, you’ll understand the annoyance I’m describing as soon as I set up this scenario.
Picture it: you’re coding away, building something cool, fetching data and manipulating objects, and suddenly you see the error, the dreaded undefined error. And your application breaks. Hard. 😑

You sigh, roll your eyes 🙄, and add yet another check into your if / else statement to prevent undefined errors like this in the future (in this case it’s making sure the genres array has a length of more than 0).
if (!loading && !error && genres.length) {
// do something here
} else {
// handle if something evaluates to not true in the if statement
}
// program continues on its merry way
But what if there was a better way?
What if, instead of checking that several objects or object properties existed before finally getting to what you want to do with that data, the good stuff, the interesting stuff, you could move on to that part even if things did evaluate to null or undefined? If your code didn’t just throw up as soon as it hit an undefined value, instead of what it was expecting?
Sounds like the stuff of dreams? Too good to be true? Not anymore.
Because JavaScript wants to do just that.
That’s what I want to talk about today: the optional chaining operator ?. proposal, which lets us read the value of a property located deep within a chain of connected objects without having to expressly validate that each reference in the chain is valid.
Optional Chaining Operators
As I alluded to in the introduction, the optional chaining operator is a proposal, which is currently in Stage 4, allowing for a sort of short-circuiting if a reference evaluates to null or undefined and returns a value of undefined instead of throwing an error the program cannot continue on from.
This boils down to shorter and simpler expressions when accessing chained properties when the possibility exists that a reference may be missing. It can also be immensely helpful while exploring the contents of an object when there’s no guarantee as to which properties are required.
Syntax of the optional chaining operator
I know this sounds a little complicated in writing, but seeing it in code should make it clearer.
Optional chaining with object properties
Here’s an example of optional chaining when accessing an object’s properties:
const simpleObj = {
levelOne: {
levelTwo: "hello world"
}
};
let nestedProp = simpleObj.levelOne?.levelThree;
console.log("There is a not a levelThree prop, it is ", nestedProp); // prints: "There is a not a levelThree prop, it is undefined"
console.log("But the program still goes on."); // prints: "But the program still goes on."
The chaining operator is actually made up of just ?.. If the operand at the left-hand side of the ?. operator evaluates to undefined or null, the expression evaluates to undefined. Otherwise the targeted property access, method or function call is triggered normally.
And you can add it to:
- An object:
a?.b - An object expression:
a?.[x] - An array:
a?.[index]or - A function’s arguments
a?.b().
And it can simplify accessing values through connected objects when it’s possible that a reference or function may be undefined or null.
Before optional chaining, everything had to be validated
Just think about how often you’ve been working with objects that have properties nested more than one level deep, and you’ve had to validate every. Single. One.
Without optional chaining, looking up a deeply-nested sub property meant validating the references in between, like so:
let newSubProperty = obj.prop && obj.prop.subProp;
The value of obj.prop is checked to be non-null and not undefined and then the value of obj.prop.subProp is accessed. This prevents the error that would have happened by attempting to access obj.prop.subProp without first checking that a value for obj.prop existed.
I don’t know about you but this felt like a lot of extra, redundant code to me.
With the optional chaining operator (?.), however, you don’t have to explicitly test and short-circuit based on the state of obj.prop before trying to access obj.prop.subProp:
let newSubProperty = obj.prop?.subProp;
By using the ?. operator, JavaScript knows to implicitly check that obj.prop isn’t a null or undefined value before attempting to access the nested subProp. If obj.prop does end up evaluating to either null or undefined, the expression short-circuits and returns an undefined value, and the program moves on.
Let’s look at some more examples of the optional chaining operator in action.
Optional chaining with function calls
You can use optional chaining when attempting to call a method which may not exist. This can be helpful when using an API in which a method might be unavailable, either due to the age of the implementation or because a feature isn’t available on the user’s device.
let response = someInterface.customFunction?.();
By using optional chaining with function calls, the expression will automatically return undefined instead of throwing an exception if the method isn’t found.
When using optional chaining with expressions, if the left operand is null or undefined, the expression just won’t be evaluated.
let possibleNull = null;
let value = 0;
let result = possible?.[value++];
console.log(value); // 0 as value was not incremented
Even though the variable possibleNull was indeed null, the variable result didn’t throw an error because the optional chaining operator kicked in. It just skipped over the function and moved on. Useful, no?
Optional chaining with object expressions
You can also use the optional chaining operator when accessing properties with an expression using the bracket notation of the property accessor. Check this out.
let nestedProp = myObj?.["prop" + "Name"];
Being able to use this with bracket notation might is useful in cases where you have a dynamic key. In my opinion, it’s a little harder to read that dot notation, but it’s there if you need it.
Array item access with optional chaining
Arrays with optional chaining are interesting, by using the optional chaining syntax you can attempt to access items within an array by the index you pass, and if that index doesn’t exist within the array it won’t error out.
let arr = [1,2,3];
let arrayItem = arr?.[3];
console.log(arrayItem) // prints: undefined
Stacked optional chaining
Another cool thing to note is that you can use optional chaining multiple times within the same nested object.
let customer = {
name: "Sean",
details: {
age: 43,
location: "Trinidad" // detailed address and subscription service frequency is unknown
}
};
let customerSubscription = customer.details?.subscription?.frequency;
console.log(customerSubscription); // prints: undefined
let customerCity = customer.details?.address?.city;
console.log(customerCity); // prints: undefined
In both variables, customerSubscription and customerCity, the value ends up being undefined because neither is defined on the customer object. But once again, an error isn’t thrown if this is the case.
You can do this same thing with functions as well: multiple optional chaining operators within function calls. Like so:
let duration = vacations.trip?.getTime?.();
Combining with the nullish coalescing operator
This is pretty useful on its own but the real power comes when optional chaining is combined with the nullish coalescing operator.
I won’t go in to great detail about this feature (also in Stage 4 proposal), but 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.
Here’s how the two proposals work together to build a default value when none is found.
let customer2 = {
name: "Paige",
details: {
age: 30 // once again a city is not provided on this object
}
};
const customerCity2 = customer2?.city ?? "City not provided";
console.log(customerCity2); // prints: "City not provided"
Since the city property is not provided and evaluates to undefined courtesy of the optional chaining operator, the, the nullish coalescing operator then kicks in and defaults to the right-hand side operand "City not provided" because the left-hand side operand evaluated to undefined.
Just think, you can create your own default values if one is missing, preventing tons of time spent debugging weird errors caused by bad data. How awesome is that? Pretty awesome in my humble opinion! 😀
Conclusion
The optional chaining operator aims to make our lives as web developers and our jobs as programmers that much simpler by eliminating errors that will break your application when object values or functions are not present.
Since the proposal is still in Stage 4 at the time of this writing it is not yet fully supported by all browsers, or standardized into the JavaScript language. Chrome, Firefox and Opera support the functionality, Edge, Safari and Internet Explorer do not.
But because it has reached Stage 4, it is now only a matter of time before it’s added to the standard ECMAScript syntax and supported across all the major browsers. You can keep an eye on the proposal in Github or the MDN Docs.
Cleaner, clearer, easier to maintain code. That’s the end game of all these improvements to the JavaScript language, and I, for one, am really excited to see the optional chaining operator coming into mainstream development soon.
Check back in a few weeks, I’ll be writing more about JavaScript, React, ES6 or something else related to web development.
Thanks for reading, I hope you’ll keep an eye out for when optional chaining gains full support and we can start simplifying our code’s null and undefined checks and putting this into production. This is going to make web development a whole lot easier.