# Optional chaining operator in JavaScript

A short an sweet guide into optional chaining operator in JavaScript.

## Which problem optional chaining addresses?

You can go one level deep in an object without getting an error:

```ts
const foo = {}
console.log(foo.bar) // undefined 👍
```

But not more:

```ts
console.log(foo.bar.baz)
// ❌ Uncaught TypeError: Cannot read properties of undefined
```

Same with a deeper object and null values:

```ts
const foo = { bar: { baz: null } }
console.log(foo.bar.baz.quix)
// ❌ Uncaught TypeError: Cannot read properties of null
```

Before optional chaining you would’ve maybe used Lodash `get()` or such:

```ts
import _ from 'lodash'
console.log(_.get(foo, 'bar.baz.quix'))
```

## Optional chaining operator

This is when we can use the `?.` syntax:

```ts
console.log(foo.bar.baz.quix?.zot) // undefined
```

Now it returns `undefined` and your program won't crash.

### Optional chaining with functions

It also works with functions methods:

```ts
const string: string | undefined = undefined
console.log(string?.trim())
```

Or you can test if a method exists, like a callback function etc:

```js
const someFunctions = (foo: string, callbackFn?: () => void) => {
  // Do something...
  return callbackFn?.()
}

// Now it doesn’t error if called without the callback fn
someFunction('Foo bar')
```

### With bracket notation

It also works when getting object values using the
[bracket notation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Property_Accessors):

```js
let foo = {
  bar: null,
}
let key = 'baz'

console.log(foo.bar?.[key]) // undefined
```

Or array index, this doesn’t do much, because calling an index that doesn’t
exist doesn’t error out. Nonetheless, it’s works:

```js
let foo = [1, 2, 3]
console.log(foo?.[3]) // undefined
```

## Conclusions

One thing to keep in mind is that extensive usage of the optional chaining
operator might add some weight to your bundles. Below is a screenshot from
[Babel compiler](https://babeljs.io/repl#?browsers=defaults%2C%20not%20ie%2011%2C%20not%20ie_mob%2011&build=&builtIns=false&corejs=3.6&spec=false&loose=false&code_lz=DYUwLgBAZg9jEF4IG8BQEICMCGAnAXCuhltgF6EB2ArsMMQL6pOqwwD8AdDrlzmVwCO1AJYAPIA&debug=false&forceAllTransforms=false&shippedProposals=false&circleciRepo=&evaluate=false&fileSize=false&timeTravel=false&sourceType=module&lineWrap=true&presets=env%2Creact%2Cstage-2&prettier=false&targets=&version=7.17.1&externalPlugins=&assumptions=%7B%7D),
where you can see that the transpiled code is much larger than the original.

I’d avoid using the optional chaining operator if not needed, for example in
this case, only the last `?.` is needed. For the related operators that handle
missing values, see
[the guide to JavaScript's logical and nullish operators](/logical-operators).

![Screenshot of the Babel REPL](/images/optional-chaining-babel.jpg)

Optional chaining operator code transpiled
