Optional chaining: What is it, and how can you add it to your JavaScript application right now?
Tags: javascript, optionalchaining, babel
Published: 2019-02-27 16:40:51

---
title: Optional chaining: What is it, and how can you add it to your JavaScript application right now?
published: true
description: Optional chaining gives you a concise way to handle issues that crop up with values in JS that may be `undefined`.
tags: javascript, optionalChaining, babel
---

_This post assumes that you're already transpiling your JS applications with Babel (version 7+). If you're not, then this probably isn't the feature to convince you to add that into your build process, but it's still a proposed language feature that is worth being aware of._

You've seen these errors before, hiding in your logs, in your automated test readouts, in your console, in your devtools: `cannot read property "map" of undefined`.

You spend time tracking down the error, and find the function in question: 

```javascript
const someFunction =
  someArray => 
    someArray.map(someOtherFunction);
```

You spend even more time looking at the code that called this function. Sometimes that array really might be undefined. In this scenario you decide that it is `someFunction`'s responsibility to handle that. You update your code, and leave a helpful comment so that no-one else wastes time wondering why you're accounting for this: 

```javascript
const someFunction =
  (someArray) => {
    // Sometimes this is undefined: See [link to bug report]
    if (someArray === undefined) {
      return [];
    }

    return someArray.map(someOtherFunction);
  }
```

This works. But, you kind of liked the implicit return from the original example. A single expression in a function makes you feel more comfortable. No way anything else can sneak in there and cause problems. I like your thinking.

You try again, with a single expression this time, using a default value:

```javascript
const someFunction = 
  (someArray = []) => 
    // Sometimes this is undefined: See [link to bug report]
    someArray.map(someOtherFunction);
```

This works. But, now your helpful comment is a bit weird. Will someone think that the _output_ of this function is undefined, and accidentally account for that possibility elsewhere, even though this will always return an array? You imagine the confusion you've potentially caused, and the accumulated (hypothetical) cost to your company as a result.

You could make your comment clearer, but you want to solve this problem using JavaScript, not boring words.

You could resign yourself to a ternary, but that would mean having to type `someArray` an extra time. Let's look at a new alternative: 

## Enter `optional chaining` 


With optional chaining, you have a new operator: `?.`

You can use `?.` on anything that you think might be undefined, which can save you from the most common and the most frustrating issues you see regularly in JS. For example: 

```javascript
const withoutOptionalChaining =
  something
    && something.someOtherThing
    && something.someOtherThing.yetAnotherThing

const withOptionalChaining =
  something
    ?.someOtherThing
    ?.yetAnotherThing
``` 

It's crucial to understand that if either `someOtherThing` or `yetAnotherThing` are `undefined`, then the `withoutOptionalChaining` example will be `false`, where the `withOptionalChaining` example will be `undefined`.

As you're aware if you've written JS for anything more than a day, `undefined is not a function`. But, what if that didn't matter? 

```javascript
const someValue = 
  someObject.someFunction?.() // returns `undefined` rather than a runtime error if `someFunction` is undefined!
```

## I'm in. But, how?

Fortunately, there's a Babel plugin for this: [@babel/plugin-proposal-optional-chaining](https://www.npmjs.com/package/@babel/plugin-proposal-optional-chaining)

Install that plugin with `npm`, and [add it to your babel config](https://babeljs.io/docs/en/plugins) via your chosen configuration option. 

Depending on the rest of your Babel config, you may also find that you end up with an error about `regenerator runtime` not being defined. If so, you may need to add the [@babel/plugin-transform-runtime](https://babeljs.io/docs/en/babel-plugin-transform-runtime) as well, and configure it like so: 

```javascript
['@babel/plugin-transform-runtime',
  {
    regenerator: true,	      
  },
]
```

If you're using ESlint, you'll find that it isn't too happy about this new operator. You'll also need to add the [babel-eslint](https://github.com/babel/babel-eslint) plugin to your ESlint config.

And that's it. Now you ought to be able to use optional chaining as much as you want to in your application.

Let's look again at that original code: 

```javascript
const someFunction =
  someArray => 
    someArray 
      // Sometimes this is undefined: See [link to bug report]
      ?.map(someOtherFunction)
      || [];
```

There we have it, another option for solving our problem. Do you always want to do this? Absolutely not: there are times when you [probably do want a runtime error](https://dev.to/nimmo/sometimes-in-the-heat-of-the-moment-its-forgivable-to-cause-a-runtime-exception-2ko2) after all. But for the rest of the time, optional chaining is a great addition to your toolkit.

## Disclaimer 


Optional chaining is currently at Stage 1 in the proposal process, so whether or not you are willing to incorporate it right now is up to you.