What is Optional Chaining?

Recently added within the ECMAScript 2020 (ES2020) language specification, the optional chaining operator creates a safe way to access nested object properties. When accessing long changes of nested object properties, if any of the properties evaluate to a nullish value (e.g. “null” or “undefined”) an error will be thrown. In the example below, we can see a pretty standard way of accessing an object’s properties, but with this way we are prone to errors if any of the intermediate properties (e.g. ‘“rhino”) do not exist.

// Will return the Rhino's name
const rhinoName = zoo.animals.rhino.name;

Another, safer, way of getting the Rhino’s name would be to use the && operator to ensure that all components exist, like so:

// Will return the Rhino's name
const rhinoName = (zoo && zoo.animals && zoo.animals.rhino && zoo.animals.rhino.name)

Whilst this is safer, it is still far from ideal as this method results in lots of duplicated code as we can see “zoo.animals” is repeated three times. It is for situations just like this, amongst others, that the optional chaining operator was added to JavaScript.

With optional chaining, we can easily grab the Rhino’s name like this:

// Will return the Rhino's name
const rhinoName = zoo?.animals?.rhino?.name

Optional chaining stops the evaluation if the value before ?. is nullish, and will then return undefined. Using the example above, if the value of “animals” is undefined, undefined will be returned instead of an error being thrown.

What I’ve covered above is just scratching the surface of the capabilities of optional chaining, if you would like to see more I’d recommend looking at the MDN Web Docs page.

How It’s Helped Me

As a CRO developer the addition of the optional chaining operator has improved my experience whenever dealing with objects.

Getting the page type from the dataLayer

When developing A/B tests, for most occasions the URL can be used to target which pages the test is to be ran on. Using the Smyths Toys website as an example, I can identify a “category”/“listing” page from the URL as the URL always ends with /c/EXAMPLE-PRODUCT-ID.

Unfortunately, some websites don’t have such a simple URL structure, but many tend to store the “page type” within the dataLayer object. We can use this dataLayer object within the code to identify if an A/B test should actually run on the page. As the dataLayer is an external object we never know all of the possible outcomes from the dataLayer, this is why the optional chaining operator really helps.

Below is a snippet from the dataLayer of a product listing page on the Boots website:

dataLayer data from a boots.com product listing page

and below is a snippet from the dataLayer of a product page (PDP) on the Boots website:

dataLayer data from a boots.com product page

From the snippets above, we can see that the page "type" property is nested within the dataLayer object. Another potential issue is that the dataLayer does not always receive these events in the same order meaning that we have to be careful to not set an explicit index position to retrieve the data that we need. See below how I'd loop through each object within the dataLayer and retrieve the page "type" value using optional chaining!

let pagetype;

// Loop though the dataLayer (array)
dataLayer.forEach(obj => {
    // If pagetype has not been found, set the pagetype variable to the page "type" value if it exits
    if(!pagetype) pagetype = obj?.page?.type;
})

This is a really basic example, but for some websites that I work with this information can be nested really deep down within the dataLayer, and optional chaining really helps reduce the code duplication whilst keeping the code easily readable!

Browser Compatibility

Compatible with:

  • Chrome (80 onwards)
  • Edge (80 onwards)
  • Firefox (74 onwards)
  • Opera (67 onwards)
  • Safari (13.1 onwards)
  • iOS Safari (13.4 onwards)
  • Chrome Android (80 onwards)
  • WebView Android (80 onwards)
  • Firefox Android (80 onwards)