Optional Chaining in JS

Optional Chaining in JS

By: Arun Shukla

Overview

As a JavaScript developer, you must know the behavior of JS. Here, we have the term optional chaining which indicates the option and something like a chain. So, Let's see ahead what is that term and where it will use for what kind of problem.

Problem Statement where optional chaining will use

Case 1:

Let's suppose you have declared an object without properties and then you want to access the properties then you will definitely get an error.

let month ={};
console.log(month.weekNumber.day)//error

You will get an error here because you are accessing the undeclared property of an object month. But if you are accessing only weekNumber, maybe you will get undefined. That's how JavaScript works.

Case 2:

In web Development, suppose you are accessing an id that you have not declared then also it will give you an error. See-through example.

const changeElement = document.querySelector("#area1");
changeElement.innerHTML = "34324"; // error

You will get an error because in this scenario you haven't declared the id "area1" in your code that's why you are getting an error.

Ternary Operators to overcome this issue

After seeing all the cases, we all think why we are not using a Ternary Operator here. So let's see with ternary Operator.

// case a
let month ={}
console.log(month.weekNumber ? month.weekNumber.day : null);
//case b
let month ={}
console.log(month.weekNumber ? month.weekNumber.day ? month.weekNumber.day.date :null :null );
//case c
const changeElement = document.querySelector("#area1");
changeElement ? changeElement.innerHTML = "32542" : null;

In all the cases (a,b,c) above, One thing is common. All have the right syntax, if the condition is fulfilled return the true statement otherwise return null. But, the common thing is that you have to write a few things many times like (changeElement in caseC, month.weekNumber in case B and A).

Using && operator

let month = {};
console.log(month.weekNumber && month.weekNumber.day && month.weekNumber.date) // NO error

In this, you will get no error as the cosole.log return something when all the cases are true otherwise false. But again you have to write the month.weekNumber so much time.

So, to overcome the repetitions Optional Chaining came into existence. Let understand.

Optional Chaining

It is nothing the simple operator which stops evaluating if it getting null or undefined before the "?." and returns undefined.

As you are seeing in the image, there is clearly mention that if the value before ?. is null or undefined it will return undefined. But if the value is defined then it will return the object property by chaining ahead the property of value. Let's understand it by example.

let month ={}
console.log(month?.weekNumber?.day)// undefined
// It will first check the month variable, if it exists then it will go to weekNUmber, if it also exists then it will return the day property. BUt if any of them are not defined or null then it will directly return undefined.

As I have mentioned above that it will check only the values before the ?. operator so it should be declared. It will not take care of the right side of the variable whether it is mentioned or not.

Optional Chaining with Parenthesis and Bracket Notation (?.() , ?.[])

You can also use parenthesis and bracket notation with an optional chaining operator. Let's see with the code:

let calendar1 = {
    date(){
           console.log(new Date);
};
let calendar2 = {};

calendar1.date?.();// Mon Feb 20 2023 16:52:47 GMT+0530 (India Standard Time)

calendar2.date?.(); // undefined

Here, you get output for calendar1 because it will first check whether the date function is in calendar1 or not. When it found the function then it will chain the parenthesis with it to call the function. And then you will get your result. But in the case of the calendar2 object, when it sees there is no definition of date in it, It directly returns undefined. You can also check with bracket notation[] with optional chaining. Let's see through an example.

let month ="May";
let calendar1 = {
    May: 31,
};
let calendar2 = null;
console.log(calendar1?.[month]); // 31
console.log(calendar2?.[month]); // undefined

Here, it goes with the same logic as it goes with parenthesis. That's why it returns the property of calendar1 instead of calendar2.

Uses with Delete

You can also use the chaining operator with the delete keyword in JavaScript. Let's see it with an example.

delete month?.[key];//true
delete calendar1.date?.();//true
delete number?.x;//true

Here it will delete the values if all the values are declared. Otherwise, it will give the Reference Error.
Note: You can use an optional chaining operator for deleting and reading but not for writing. Let's see with an example.

For example:

let value = null;

value?.name = "Arun"; // Error, It will not work because it evaluates to undefined due to optional chaining operator. So, it will look like undefined = Arun which is not valid in JavaScript.

Short-Circuiting

As I have mentioned above, the optional chaining operator stops immediately if the left part of the operator is null or undefined. So if there is any function call or some other operation on the right side, it wouldn't call. Let's see via an example.

let justTry = null;
let count =0;
function IncrementTheCount(num){
    return num++;
    }
justTry?.IncrementTheCount(count);// undefined
console.log(count);// 0

Here, you will get the undefined as a return because justTry is null that's why the function IncrementTheCount wouldn't call and the value of count remains the same.

Summary

  1. By reading the above part we know that the optional chaining operator will only evaluate if the left part of the user is defined otherwise it will return undefined.

  2. You can use the optional Chaining operator with three cases:

    1. value?.x : returns value.x if the value is declared, otherwise returns undefined.

    2. value?.[x]: returns value[x] if the value is declared, otherwise returns undefined.

    3. value.x?.() : calls value.x(), if value.x exists, otherwise returns undefined.

  3. This operator will help you to safely access the nested property.

  4. This operator will also help you to write short code as much as possible.

    1.     //Don't overuse the ?. operator. This means if you know the month is declared then don't use ?. operator with month, Use with their properties which is optional.
          let month ={}
          month?.weekNumber?.day; // this is the wrong way. As the month is already declared then there is no use of ?. operator with month.
          month.weekNumber?.day// Use in this way instead of the upper one because month is already declared in the code but the property weekNumber is not declared so to check it you can use ?. operator here.
      
  5.   //The variable you are using before the ?. operator must be declared otherwise you will get a reference error.
      anotherValue?.x;// Reference Error
    
      // so to fix this you will first declare anotherValue first.
    
      let anotherValue = {
      x:5;}
      console.log(anotherValue?.x) //5
    

So, here I am ending this blog. If you still facing any misunderstanding while reading then comment down, I will be here to clear your doubt. Thank you for reading guys. Keep React :-)...