Navigate back to the homepage

Optional Chaining for Javascript - ES proposal

Amit Solanki
November 30th, 2019 · 1 min read

We saw nullish coalescing yesterday, today let’s see optional chaining another awesome ESnext feature. It is so awesome not to talk about.

Just like nullish coalescing, optional chaining helps us handle undefined and null cases. let’s consider the following example

1let company = {
2 name: 'Github',
3 revenue: 2000,
4 users: [
5 { name: 'John', handle: '@john' },
6 { name: 'doe', handle: '@doe' },
7 ],
8 getUserNames() {
9 return users.map(user => user.name)
10 },
11}

to access the values of this object, if they or the object can be undefined or null we would normally do the following.

1const companyName =
2 company !== undefined && company !== null ? company.name : undefined

In contrast with optional chaining we can do

1const companyName = company?.name

The Syntax

1obj?.prop // optional static property access
2obj?.[expr] // optional dynamic property access
3func?.(...args) // optional function or method call

Let’s see how we can handle multiple ways of accessing properties of an object.

  1. Static
  2. Dynamic
  3. Function Call
  4. Dom access

Static Properties

1let company = {
2 name: 'Github',
3 revenue: 2000,
4 users: [
5 { name: 'John', handle: '@john' },
6 { name: 'doe', handle: '@doe' },
7 ],
8 getUserNames() {
9 return users.map(user => user.name)
10 },
11}
12
13// with optional Chaining
14const companyName = company?.name
15
16// without optional Chaining
17const companyName =
18 company !== undefined && company !== null ? company.name : undefined

Dynamic Properties

1let company = {
2 name: 'Github',
3 revenue: 2000,
4 users: [
5 { name: 'John', handle: '@john' },
6 { name: 'doe', handle: '@doe' },
7 ],
8 getUserNames() {
9 return users.map(user => user.name)
10 },
11}
12
13// with optional Chaining
14const companyName = company?.['name']
15
16// without optional Chaining
17const companyName =
18 company !== undefined && company !== null ? company['name'] : undefined

Function calls

1let company = {
2 name: 'Github',
3 revenue: 2000,
4 users: [
5 { name: 'John', handle: '@john' },
6 { name: 'doe', handle: '@doe' },
7 ],
8 getUserNames() {
9 return users.map(user => user.name)
10 },
11}
12
13// with optional Chaining
14company.getUserNames?.()
15
16// without optional Chaining
17const companyName =
18 company !== undefined &&
19 company !== null &&
20 Object.prototype.hasOwnProperty('getUserNames') &&
21 typeof company.getUserNames === 'function'
22 ? company['name']
23 : undefined

Dom access

Optional Chaining supports DOM and its methods, so we can do stuff like this

1const val = document.querySelector('input#name')?.value

Optional Chaining will always return undefined if the expression fails.

1const value = company?.name
2
3// 'value' will be undefined if company is undefined.

So we can pair optional chaining with nullish coalescing to handle those cases.

1const value = company?.name ?? 'default name'
2
3// 'value' will be 'default name' if either the company or name is undefined or null.

To wrap it up with a complete example

1let company = {
2 name: 'Github',
3 revenue: 2000,
4 users: [
5 { name: 'John', handle: '@john' },
6 { name: 'doe', handle: '@doe' },
7 ],
8 getUserNames() {
9 return users.map(user => user.name)
10 },
11}
12
13// Static access with default value
14const value = company?.name ?? 'default name'
15
16// Dynamic access with default value
17const companyName = company?.['name'] ?? 'default value'
18
19// Function call
20company.getUserNames?.()

Optional chaining and nullish coalescing brings a lot of benefits, by reducing the complexity and making code readable. Give them a try and let me know your opinions in comments below.

You can use the following babel plugins to use them today.

Follow me on twitter

More articles from Amit Solanki

Nullish Coalescing for JavaScript

Understanding the Null coalescing operator, an ES features which is moved to stage 3.

November 29th, 2019 · 1 min read

Handling CORS in Rails for client side apps

Handling CORS in Rails for JS apps using React, etc

January 20th, 2019 · 1 min read
© 2018–2019 Amit Solanki
Link to $https://twitter.com/iamsolankiamitLink to $https://github.com/iamsolankiamit