Optional chaining (?.)
Tags: javascript, webdev, tutorial, beginners
Published: 2020-07-20 15:14:45

<!-- wp:paragraph -->
<p>The&nbsp;<strong>optional chaining</strong>&nbsp;operator (<strong><code>?.</code></strong>) permits reading the value of a property located deep within a chain of connected objects without having to expressly validate that each reference in the chain is valid.&nbsp;The&nbsp;<code>?.</code>&nbsp;operator functions similarly to the&nbsp;<code>.</code>&nbsp;chaining operator, except that instead of causing an error if a reference is&nbsp;<a href="https://developer.mozilla.org/en-US/docs/Glossary/nullish">nullish</a>&nbsp;(<a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/null"><code>null</code></a>&nbsp;or&nbsp;<a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined"><code>undefined</code></a>), the expression short-circuits with a return value of&nbsp;<code>undefined</code>.&nbsp;When used with function calls, it returns&nbsp;<code>undefined</code>&nbsp;if the given function does not exist.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3>Content</h3>
<!-- /wp:heading -->

<!-- wp:list {"ordered":true} -->
<ol><li>The Problem</li><li>Why Optional chaining</li><li>Optional chaining not valid on the left-hand side of an assignment</li><li>Relationship with the optional chaining operator (?.)</li><li>Other cases: ?.(), ?.[]</li><li>Use <code>?.</code> with delete:</li><li>Summary</li><li>Reference</li></ol>
<!-- /wp:list -->

<!-- wp:heading -->
<h2>The problem</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>An object can have a very different nested structure of objects.</p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul><li>Fetching remote JSON data</li><li>Using configuration objects</li><li>Having optional properties</li></ul>
<!-- /wp:list -->

<!-- wp:separator -->
<hr class="wp-block-separator"/>
<!-- /wp:separator -->

<!-- wp:paragraph -->
<p>Working with data in JavaScript frequently involves situations where you aren’t sure that something exists. For example, imagine getting a JSON response from a weather API.</p>
<!-- /wp:paragraph -->

```javascript
{
  "data": {
    "temperature": {
      "current": 68,
      "high": 79,
      "low": 45
    },
    "averageWindSpeed": 8
  }
}
```

<!-- wp:paragraph -->
<p>You can go through each level of the object to get the <strong>high</strong> temperature.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>The value of <code>response.data</code>, <code>response.data.temperature</code> are confirmed to be non-null before accessing the value of <code>response.data.temperature.current</code>. This prevents the error that would occur if you simply accessed <code>response.data.temperature.current</code> directly without testing <code>response.data &amp;&amp; response.data.temperature</code></p>
<!-- /wp:paragraph -->

```javascript
const highTemperature = response.data && response.data.temperature && response.data.temperature.current;
```

<!-- wp:paragraph -->
<p>With the optional chaining operator(?.) you don't have to explicitly test and short-circuit based on the state of <code>response.data &amp;&amp; response.data.temperature</code> before trying to access <code>response.data.temperature.current</code>.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>If <code>response.data &amp;&amp; response.data.temperature</code> are null or undefined, the expression automatically short-circuits, returning undefined.</p>
<!-- /wp:paragraph -->

```javascript
const highTemperature = response.data?.temperature?.current;
```

<!-- wp:paragraph -->
<p>By using the <code>?.</code> operator instead of just <code>.</code>, JavaScript knows to implicitly check to be sure <code>response.data &amp;&amp; response.data.temperature</code> are not null or undefined before attempting to access response.data.temperature.current</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3>Optional chaining not valid on the left-hand side of an assignment</h3>
<!-- /wp:heading -->

```javascript
let object = {};
object?.property = 1; // Uncaught SyntaxError: Invalid left-hand side in assignment
```

<!-- wp:heading {"level":3} -->
<h3>Relationship with the optional chaining operator (<code>?.</code>)</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>The nullish coalescing operator treats&nbsp;<code>undefined</code>&nbsp;and&nbsp;<code>null</code>&nbsp;as specific values and so does the&nbsp;<a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining">optional chaining operator (<code>?.</code>)</a>&nbsp;which is useful to access a property of an object which may be&nbsp;<code>null</code>&nbsp;or&nbsp;<code>undefined</code>.</p>
<!-- /wp:paragraph -->

```javascript
let foo = { someFooProp: "hi" };

console.log(foo.someFooProp?.toUpperCase());  // "HI"
console.log(foo.someBarProp?.toUpperCase()); // undefined
```

<!-- wp:heading {"level":3} -->
<h3>Other cases: ?.(), ?.[]</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>The optional chaining&nbsp;<code>?.</code>&nbsp;is not an operator, but a special syntax construct, that also works with functions and square brackets.</p>
<!-- /wp:paragraph -->

```javascript
let user1 = {
  admin() {
    alert("I am admin");
  }
}

let user2 = {};

user1.admin?.(); // I am admin
user2.admin?.();
```

<!-- wp:separator -->
<hr class="wp-block-separator"/>
<!-- /wp:separator -->

<!-- wp:heading {"level":3} -->
<h3>Use <code>?.</code> with delete</h3>
<!-- /wp:heading -->

```javascript
delete user?.name; // delete user.name if user exists
```

<!-- wp:heading {"level":3} -->
<h3>Few Scenario which needs to taken care of:</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p><strong>1.    The variable before ?. must be declared</strong></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>     If there’s no variable user at all, then user?.anything triggers an error:</p>
<!-- /wp:paragraph -->

```javascript
// ReferenceError: user is not defined
user?.address;
```

<!-- wp:paragraph -->
<p>There must be let/const/var user. The optional chaining works only                           for declared variables.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p><strong>2.     Use ?. for safe reading and deleting, but not writing</strong></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>The optional chaining ?. has no use at the left side of an assignment:</p>
<!-- /wp:paragraph -->

```javascript
// the idea of the code below is to write user.name, if user exists

user?.name = "John"; // Error, doesn't work
// because it evaluates to undefined = "John"
```

<!-- wp:heading {"level":3} -->
<h3>Summary</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>The&nbsp;<code>?.</code>&nbsp;syntax has three forms:</p>
<!-- /wp:paragraph -->

<!-- wp:list {"ordered":true} -->
<ol><li><code>obj?.prop</code>&nbsp;– returns&nbsp;<code>obj.prop</code>&nbsp;if&nbsp;<code>obj</code>&nbsp;exists, otherwise&nbsp;<code>undefined</code>.</li><li><code>obj?.[prop]</code>&nbsp;– returns&nbsp;<code>obj[prop]</code>&nbsp;if&nbsp;<code>obj</code>&nbsp;exists, otherwise&nbsp;<code>undefined</code>.</li><li><code>obj?.method()</code>&nbsp;– calls&nbsp;<code>obj.method()</code>&nbsp;if&nbsp;<code>obj</code>&nbsp;exists, otherwise returns&nbsp;<code>undefined</code>.</li></ol>
<!-- /wp:list -->

<!-- wp:heading {"level":3} -->
<h3>Reference:</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining">MDN Optional chaining</a></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p><a rel="noreferrer noopener" href="https://javascript.info/optional-chaining" target="_blank">optional chaining from <a rel="noreferrer noopener" href="https://javascript.info/optional-chaining" target="_blank">Javascript Info</a></a></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Thanks for reading the article ❤️</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>I hope you get to learn something new from this article. If you have any question please reach out to me on <a href="https://twitter.com/suprabhasupi">@suprabhasupi</a> 😋</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p></p>
<!-- /wp:paragraph -->

<table>
  <tbody>
    <tr>
      <td>
        🌟 <a href="https://twitter.com/suprabhasupi"> Twitter</a>
      </td>
      <td>
        👩🏻‍💻 <a href="https://www.suprabha.me/"> Suprabha.me</a>
      </td>
<td>
        🌟 <a href="https://www.instagram.com/suprabhasupi/"> Instagram</a>
      </td>
    </tr>
  </tbody>
</table>