Optional Chaining ⛓️
Tags: react, beginners, javascript
Published: 2020-10-16 12:53:07

Before we start to understand _optional chaining,_ we should understand `undefined` and what the motivation behind _optional chaining_ is.

## `undefined`

```javascript
const me = {
  name: "CodeFinity",
  age: 300, 
}

console.log(me.handles); // undefined
```

With our _composite data types_ - _collections_ such as _object literals_ 👆🏽 - if access a 🔑 that doesn't exist we get back a special _primitive data type,_ **`undefined`**.

Yea, it's a bit weird that JS has its own 'special data type' and even weirder that we have yet another _primitive data type,_ `null` (we'll deal with that in the next post in this series).

Nevertheless, hopefully at this point you can accept that the `handles` is a `key` that has 'no definition' within the context of `me`👆🏽. 

**At this point, JS is not 'error-ing out'** - it's 🙆🏽‍♂️ with `undefined`
Now, referencing `me` 👆🏽 once again, what if we did: `console.log(me.handles.twitter)`❓ 

`Uncaught TypeError: Cannot read property 'twitter' of undefined `

### Observations

1. Accessing a 🔑 within an _object literal_ that doesn't exist is 🙆🏽‍♂️ - it's `undefined`.
2. Accessing a 🔑 on _something that is `undefined`_ is 🙅🏽‍♂️ - it creates an error❗

`undefined` is its own _primitive data type._ It's **not** a collection type. Therefore anytime that we invoke `.` on `undefined`, JS is going to have a problem with that. By definition, _primitive data types_ are _discrete values;_ they cannot hold any 🔑s! That's what that error message is telling us 👆🏽.

## Preventing Our Program From Crashing 😑

Referencing again, the attempt to access: `me.handles.twitter` 👆🏽, without _optional chaining,_ I might have to write my code like this one:

```javascript
// Referencing 'me' 👆🏽

if (me.handles) {
  console.log(me.handles.twitter)
}
```

Now, my program will not crash because we will never reach the line: `console.log(me.handles.twitter)`.

Instead, JS will apply _implicit coercion_ to: `me.handles`. This just means that since we are using `if`, 'under the hood,' JS will look at the `undefined` _value_ that stems from `me.handles` and will 'coerce' it to `false` (it's a 'false-y' value). So, that code inside of the `{` after that `if` will not run.

### Short-Circuit `&&` Approach

We could also do this by _short circuiting `&&`: `me.handles && console.log(me.handles.twitter)`.

This time, when `me.handles` gets' _implicitly coerced_ to `false` the right-hand side _operand_ of `&&` will never get run 🍦.

### Ternary Approach

We could also shorten that code by using a _ternary:_

```javascript
// Referencing 'me' 👆🏽

console.log(me.handles ? me.handles.twitter : "");
```

JS would again, _implicitly coerce_ `me.handles` to `false` and would take the right hand side _operand_ of the `:` _operator,_ `""`, thereby `log`ging that empty _string._

## Use Optional Chaining - `?.` - to Prevent Our Program From Crashing 🤓

`console.log(me.handles?.twitter)`

This syntax sort of applies the _ternary,_ but in a simpler way. That `.` after `?` is the 'optional' part of this.

First, we are asking the a ❓, "Hey, JS, does `me.handles` come back as an _object literal_?" If so, then go ahead with this next part of my _chain._ If not, _please_ don't freak out 😱...let's just leave it as `undefined` and move on. 

## Examples

```javascript
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining
const adventurer = {
  name: 'Alice',
  cat: {
    name: 'Dinah'
  }
};

const dogName = adventurer.dog?.name;
console.log(dogName);
// expected output: undefined

console.log(adventurer.someNonExistentMethod?.());
// expected output: undefined
```

Yes, this works for _methods_ also: `console.log(adventurer.someNonExistentMethod?.());`

Here's another example from that same MDN link (slightly modified):

```javascript
const customer = {
  name: "Carl",
  details: {
    age: 82,
    location: "Paradise Falls" // detailed address is unknown
  }
};

const customerCity = customer.details?.address?.city;
```

From this one, we see that we can chain _optional chaining._

## ⚠️

I should mention that _optional chaining_ is an ES2020 thing. This means that unless you are using something like [Babel](https://babeljs.io/) as part of your build process, you will probably not be able to use this feature in your code today. For example, a Node.js repl.it will freak out about this. However, Chrome Dev Tool's console can use _optional chaining._