
Optional Chaining in JavaScript (?.)

If you've worked with JavaScript before, you know how frustrating it can be to handle nested object properties, especially if you're trying to keep your code DRY, succinct, and optimised.
Rather than returning undefined or null when you try to access a child property that doesn't exist, which would be helpful, JavaScript rather frustratingly throws an error and stops executing altogether. If you want to avoid errors, you have to manually check whether properties exist before you can work with them ‑ repeating the object and properties in an if statement before you actually try to access it.
Some example code that came up recently during a code review. I should be clear: I do not recommend this, and I'll explain why further down the page...
const model = car && car.manufacturer && car.manufacturer.model ? car.manufacturer.model ? null;Not to repeat myself, but please don't do this.
What's the Problem?
The example I've been working on most recently aggregates music data, so that seems like a good basis for my examples.
Let's say we're working with a music listing site. Each artist has a listing page that just displays albums with their tracklists and cover art. For each album, we put together a JavaScript object which contains all the necessary information. We can't always trust that our content team will have entered all of the information correctly, though!
So, to grab the source of the album cover, we might start off with something like this:
console.log(album.coverArt.url);This is a risky way to access your album art because JavaScript will throw an error if the coverArt property isn't set. We can mitigate this scenario by using an if statement (like the code review snippet I included earlier). I'm going to use long‑form if statements rather than shorthand here, just because it's more illustrative of what we're doing:
if (album.thumbnail) { console.log(album.coverArt.url);}As a single‑level check, this isn't too bad but it would be handy if we didn't need that if statement. This quickly becomes more complex though; what if our coverArt object had multiple URLs ‑ for example ‑ for different image sizes?
if (album.coverArt) { if (album.coverArt.url) { console.warn(album.coverArt.url.thumbnail); }}This starts to look a lot like the car manufacturer ternary function I keep referring back to. This is messy, and this still is not an especially complex example.
What if we had a user object, with things like addresses? We would have to chain if statements all the way down. Aside from being a huge waste of space, this becomes repetitive and unwieldy very quickly...
Optional Chaining ‑ the Solution
Thankfully as part of the ES2020 spec JavaScript has introduced a syntax that can solve this issue for us. Quite simply, you replace . with ?.. Using this, we can condense the entire chain of if statements down into an effective shorthand, like this:
console.log(album?.coverArt?.url?.thumbnail);This won't throw an error, even if the coverArt property isn't present. It will return undefined, which is far preferable because that's something we can test against. Not only does it mean that our entire method doesn't crash, but it also means we can make a decision about what to do with our thumbnail component: maybe simply not render it at all, or otherwise display an 'Album art missing' type placeholder image instead.
What makes this even cooler ‑ and discussed far less in my experience ‑ is that we can also use this operator with methods and the square bracket syntax too. Following on from our music platform example, what if our product had a deal which meant that some artist pages used affiliate links? In our instance, this was delivered via an aged back‑end system and a function. This meant that we would have to first check whether the function existed for that specific artist:
album.affiliateLinkClick?.()This will trigger and run the affiliateLinkClick function if it exists, and otherwise simply won't do anything aside from return undefined.
This optional chaining syntax will hopefully help you cut down on repeated code or wasted characters in your work ‑ and it helps to keep your code clear and easy to read, too.
Categories:
Related Articles

Semantic HTML. 
Understanding CSS Positioning. Understanding CSS Positioning
How to Check an Element Exists with and Without jQuery. How to Check an Element Exists with and Without jQuery

Ethical Web Development ‑ Part II. Ethical Web Development ‑ Part II

Trigonometric Functions in CSS. Trigonometric Functions in CSS

JavaScript's typeof Operator: Uses and Limitations. JavaScript's
typeofOperator: Uses and Limitations
Adaptive vs. Responsive Design & Development. Adaptive vs. Responsive Design & Development

Commenting in JSX. Commenting in JSX

Optimising gatsby‑image Even Further. Optimising
gatsby‑imageEven Further
Object Control in JavaScript: defineProperties(). Object Control in JavaScript:
defineProperties()
LeetCode: Solving the 'Merge Two Sorted Lists' Problem. LeetCode: Solving the 'Merge Two Sorted Lists' Problem

JavaScript Hoisting: Variables, Functions, and More. JavaScript Hoisting: Variables, Functions, and More