fbpx

What is Optional Chaining in JavaScript?

Optional Chaining is a new Operator in JavaScript, which might be not supported by the old version of the browser. Most of the latest versions of the browser support this operator.

Why this is required ?

While working on the object and we want to access each of object then we have to handle a various scenario like object should not be null or undefined and the property that needs to access should be available to use etc.

To handle these cases we have to use nested if-else or multiple && operations to avoid any error or code failure.

let user = {} // without any name property
console.log(user.name) // undefined
console.log(user.name.lastname) // Cannot read property 'lastname' of undefined

To handle above scenario we need to either use if-else or && operator to avoid any error

if (user && user.name && user.name.lastname) {
  console.log(user.name.lastname);
}

Optional Channing

The optional chaining ?. operator provides a way to simplify accessing values through connected objects when it’s possible that a reference or function may be undefined or null.

In other words optional chaining (?.) operator does evaluate the right-hand side, if the left-hand side of the operator is null or undefined.

let user = {} // without any name property
console.log(user?.name) // undefined
console.log(user?.name?.lastname) // undefined

Syntax:
obj?.prop
obj?.[expr]
arr?.[index]
func?.(args)

let user = null;
console.log( user?.name); // undefined
console.log( user?.name.lastname); // undefined

In the above code, we can see the evaluation of code stop after user?. as the user was null. But if the user is not null then name.lastname should exist otherwise it will throw an error.

let nestedProp = obj.first?.second;

By using the ?. operator instead of just ., JavaScript knows to implicitly check to be sure obj.first is not null or undefined before attempting to access obj.first.second. If obj.first is null or undefined, the expression automatically short-circuits, returning undefined.

This is equivalent to the following, except that the temporary variable is in fact not created:

let temp = obj.first;
let nestedProp = ((temp === null || temp === undefined) ? undefined : temp.second);

Tip: #1: The variable before ?. must exist.
The optional chaining only tests for null/undefined, doesn’t interfere with any other language mechanics.

user?.name.lastname // Reference error as user does not exist

Short-circuiting evaluation:

When using optional chaining with expressions, if the left operand is null or undefined, the expression will not be evaluated (short-circuit) . For instance:

let potentiallyNullObj = null;
let x = 0;
let prop = potentiallyNullObj?.[x++];
console.log(x); // 0 as x was not incremented

Optional chaining with function calls:

We can use optional chaining when attempting to call a method which may not exist. Using optional chaining with function calls causes the expression to automatically return undefined instead of throwing an exception if the method isn’t found.

let user = {
x : 0,
z : null,
y : function() { console.log("Hello Optional")} }
user.z?.() // undefined
user.y?.() // Hellow Optional

Tip #2: If there is a property with such a name and which is not a function, using ?. will still raise a TypeError exception (x.y is not a function).

user.x?.() //user.x is not a function
// Using optional chaining with function calls
function doSomething(onContent, onError) {
  try {
   // ... do something with the data
  }
  catch (err) {
    onError?.(err.message); // no exception if onError is undefined
  }
}

Array item access with optional chaining:

let arr = null;
let arrayItem = arr?.[42]; //undefined

Combining with the nullish coalescing operator:

The nullish coalescing operator may be used after optional chaining in order to build a default value when none was found:

let customer = {
  name: "Carl",
  details: { age: 82 }
};
const customerCity = customer?.city ?? "Unknown city";
console.log(customerCity); // Unknown city

delete operation with Optional Channing:

let user = {name:'singhak', lastname:".in"}
// delete name if user exist
delete user?.name // true

Tip #3: Optional chaining not valid on the left-hand side of an assignment

user?.fullname = 'singhak.in' //Uncaught SyntaxError: Invalid left-hand side in assignment

Summary

  • We can use optional chaining (?.) operator with a function call, accessing object property, or accessing the array.
  • We should avoid overuse of this. It may cause hiding programming error, which is not good for an application
  • We can use this with nullish coalescing operator to assign the default value.

References: