Optional Chaining in JavaScript (?.)

Hero image for Optional Chaining in JavaScript (?.). Image by Jordan Hopkins.
Hero image for 'Optional Chaining in JavaScript (?.).' Image by Jordan Hopkins.

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 longform 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 singlelevel 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 backend 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:

  1. Development
  2. Front‑End Development
  3. JavaScript