Table of contents
1.
Introduction
2.
The “non-existing property” problem
3.
Optional chaining
4.
Short-circuiting
5.
Other variants: ?.(), ?.[]
6.
Conclusion
7.
FAQs
8.
Key takeaways
Last Updated: Mar 27, 2024

Optional chaining

Career growth poll
Do you think IIT Guwahati certified course can help you in your career?

Introduction

In this article, we are going to learn about optional chaining and how they are helpful. But before moving ahead, let’s understand what exactly is this optional chaining. 

This is a recent addition to the javascript language. In the absence of intermediate properties, nested object properties can be easily accessed by this optional chaining. Earlier the work was performed by polyfills. Sounds confusing, right!!. Let’s understand it in more detail.

    Source: Giphy

 

The “non-existing property” problem

If you are just a beginner and started learning javascript, then the problem might not have knocked on your door yet. But to be honest. This is a very common problem faced by almost every second developer.

 

Let’s say we have a user object which is containing various information about the users. 

 

Mostly the details are contained in the user.address property. Along with the street user.address.they do not provide street, but some. In such cases where the user has no address present,, and we try to get the user.address.street, we end up getting an error.

<!DOCTYPE html>
<script>
"use strict";

let user = {}; // a user without "address" property

alert(user.address.street); // Error!
</script>

 

Here, the user.address is not defined, so an attempt to get user.address.street will give an error. In a practical scenario, such a scenario is termed as undefined meaning “no street.”

 

Let’s take another example…

<!DOCTYPE html>
<script>
"use strict";

// When there is no element, document.querySelector('.elem') is null.
let html = document.querySelector('.elem').innerHTML; // error if it's null
</script>

 

Here, since the element doesn’t exist, on calling the .innerHTML, we will be getting an error. Now, if the absence of the element is quite normal, we will be avoiding the error and just accept HTML=null as a result. But how??

Let’s find that out.

 

The naive approach to receive this is to verify the value using the if or the conditional operator? Before its property is accessed. The syntax for the same is:

let user = {};

alert(user.address ? user.address.street : undefined);

 

This works, giving no error. But this way of doing it is not worthy enough as the “user.address” appears twice in the code.

Now, let’s try getting user.address.street.name and for getting both the things we need to check user.address as well as user.address.street.

let user = {}; // user has no address

alert(user.address ? user.address.street ? user.address.street.name : null : null);

 

Another way of writing this code is using && operator.

<!DOCTYPE html>
<script>
"use strict";

let user = {}; // user has no address

alert( user.address && user.address.street && user.address.street.name ); // undefined (no error)
</script>

 

Output:


The presence of a whole path to the property checks that all components exist. It’s clear from the code that the property names are still duplicated. Let’s say the user.address, its appearing three times in the code. Hence, to avoid these duplication parts, optional chaining was introduced into the picture. 

 

Optional chaining

Using optional chaining ‘?’, the evaluation gets stopped if the value before ? is null or undefined. The value returned is undefined. And if it is not null or undefined, then it implies something exists. In other words, value?.prop implies:

  • If the value exists, it works as value.prop.
  • If the value is undefined or null, it returns undefined.
<!DOCTYPE html>
<script>
"use strict";

let user = {}; // user has no address

alert( user?.address?.street ); // undefined (no error)
</script>

Output:

The code given above is very short and clean. It has no duplicate. Here the syntax ?. makes the value optional. Let’s take an example, the user?.address.street.name. The ?. here implies the user can be null/undefined. Other properties are accessed in a general way. If we want some of the properties to behave optionally, we need to change the . With?. more.

 

⚠ Never overuse the optional chaining excessively

The ?. should only be used when something doesn’t exist. From the examples we have already seen before, the user object has to be there, and the address is optional. Hence, we are able to write user.address?.street. But if we write user?.address?.street, this is wrong as it’s not making any sense.

So, if a user has mistakenly overused the ?. operator, we will see an error, and it can be sorted out quickly. 

 

The variables must be declared before ?.

If the variable user is not present, user?.anything will provide an error. 

<!DOCTYPE html>
<script>
"use strict";

// ReferenceError: user is not defined
user?.address;
</script>

 

In the code snippet above, the user is not defined. Hence it will throw an error. The variable must be declared(let or var or const). Optional chaining is only valid for defined and declared variables.

 

Short-circuiting

As the name suggests, if any statement is not present before the ?. part, then the circuit breaks and the program execution stops In such cases, the other statement remains untouched.

<!DOCTYPE html>
<script>
"use strict";

let user = null;
let y = 0;

user?.sayHi(y++); // no "sayHi", so the execution doesn't reach y++

alert(y); // 0, value not incremented
</script>

 

Output:

 

Other variants: ?.(), ?.[]

The ?. optional chaining is not any operator as such. They are just a special syntax construct that works well with functions and square brackets.

Let’s say, ?.() this can be used to call a not available function have.

<!DOCTYPE html>
<script>
"use strict";

let userAdmin = {
  admin() {
    alert("I am admin");
  }
};

let userGuest = {};

userAdmin.admin?.(); // I am admin

userGuest.admin?.(); // nothing (no such method)
</script>

 

Output:

In the above code snippet, some users are having an admin method, while some are not. In the last two lines of our code, we have used the dot(.) operator to get the admin property. And we are assuming that the user property exists.

The ?.() is used to check the left part of the statement. If the admin function is existing, then it gets successfully executed. And if it’s not present, the execution stops, then and there itself.

The ?.[] is used to get the properties instead of the dot. Just like the previous cases, any property from the object can be safely read that may even don’t exist.

<!DOCTYPE html>
<script>
"use strict";

let key = "firstName";

let user1 = {
  firstName: "John"
};

let user2 = null;

alert( user1?.[key] ); // John
alert( user2?.[key] ); // undefined
</script>

Output:

Additionally, ?. can also be used with delete. The syntax for the same looks like this:

<!DOCTYPE html>
<script>
"use strict";

delete user?.name; // delete user.name if user exists
</script>

 

⚠ For safe purpose ?. can be used for reading and deleting, but not writing

 

As we have already seen that we don’t have any impact of ?. on the left side.

<!DOCTYPE html>
<script>
"use strict";

let user = null;

user?.name = "John"// Error, doesn't work
// because it evaluates to undefined = "John"
</script>

 

Conclusion

The optional chaining ?. has three forms:

  • Obj?.prop: this returns obj.prop if the object exists; otherwise, it will return undefined.
  • Obj?.[prop]: this returns obj[prop], if the object exists, otherwise undefined.
  • obj.method.?(): this returns the obj.method(), if exists. Otherwise, returns null.

 

Overall, we concluded that the optional chaining ?. is very simple to use. It checks the left part and checks for the undefined or null portion, if it is not, then the execution proceeds further. The chain of ?. allows to access all the nested properties very easily. 

 

For better understanding try it on the online JS editor.

 

FAQs

  1. When optional chaining should be used?
    Optional chaining is generally preferred to call a method when don’t even exist. This is used for calling an API in which a method might be unavailable due to implementation age or the information availability on user’s device.
     
  2. When the idea of optional chaining come into existence?
    The latest version of Typescript was added on 5 November 2019. That version includes the ideology of optional chaining.
     
  3. Is the usage of optional chaining beneficial?
    As such there is nothing wrong with optional chaining. The idea helps to solve issues related to idiomatic values in Javascript and it is null or undefined. 

Key takeaways

This article begins its discussion with the introduction of optional chaining, their usage, perks of using optional chaining, and how they came into existence. We further covered some interesting topics like short-circuiting and came to final conclusion.

Live masterclass