Optional Chaining

Learn how JavaScript Optional Chaining (?.) works, and how to safely access deeply nested properties without runtime errors.

Loading...
Optional Chaining

When you access a deeply nested property in JavaScript, JavaScript gives an error like Cannot read property 'x' of undefined.

That's frustrating, right? 😖

Optional chaining (?.) solves this problem. It allows you to safely access deeply nested values without worrying about breaking your code when something in the chain is null or undefined.

What is Optional Chaining?

Optional chaining is a feature in JavaScript introduced in ES2020 that lets you access properties of an object without throwing an error, even if they are null or undefined.

Syntax:

object?.property;
object?.[expression];
object?.method?.();

If the left-hand side is null or undefined, it short-circuits and returns undefined, instead of throwing an error.


Why Use Optional Chaining?

Before optional chaining, accessing deeply nested missing properties could crash your app.

const user = {};
 
console.log(user.address.country); // Error: Cannot read property 'country' of undefined

Now with optional chaining:

console.log(user.address?.country); // Output: undefined

Examples of Optional Chaining

Accessing a Nested Property

Without optional chaining:

const user = {
  name: "Shefali",
  address: {
    country: "India",
  },
};
 
console.log(user.address.country); // Output: India
console.log(user.profile.bio); // Uncaught TypeError: user.profile is undefined

With optional chaining:

const user = {
  name: "Shefali",
  address: {
    country: "India",
  },
};
 
console.log(user.address?.country); // Output: India
console.log(user.profile?.bio); // Output: undefined

Accessing an Array Item Safely

Without optional chaining:

const users = null;
 
console.log(users[0]); // Uncaught TypeError: users is null

With optional chaining:

const users = null;
 
console.log(users?.[0]); // Output: undefined

Calling a Method Safely

Without optional chaining:

const user = {
  sayHi: () => console.log("Hello!"),
};
 
user.sayHi(); // Output: Hello!
user.sayBye(); // Uncaught TypeError: user.sayBye is not a function

With optional chaining:

const user = {
  sayHi: () => console.log("Hello!"),
};
 
user.sayHi?.(); // Output: Hello!
user.sayBye?.(); // Output: undefined (no error thrown)

If the method doesn't exist, JavaScript won't throw an error, it just skips the call.

API Responses

Without optional chaining:

const apiResponse = {
  data: {
    user: {
      profile: { name: "Shefali" },
    },
  },
};
 
console.log(apiResponse.data.user.profile.name); // Output: 'Shefali'
console.log(apiResponse.data.user.settings.theme); // Uncaught TypeError: apiResponse.data.user.settings is undefined

With optional chaining:

const apiResponse = {
  data: {
    user: {
      profile: { name: "Shefali" },
    },
  },
};
 
console.log(apiResponse.data?.user?.profile?.name); // Output: 'Shefali'
console.log(apiResponse.data?.user?.settings?.theme); // Output: undefined

Optional Chaining with Nullish Coalescing

You can combine optional chaining with the nullish coalescing ?? operator to provide a default value.

For example:

const user = {};
 
const bio = user.profile?.bio ?? "No bio available!";
 
console.log(bio); // Output: No bio available!

If profile or bio doesn’t exist, it returns the fallback.


Things to Keep in Mind

  • You can only use ?. on something that might be null or undefined. If the object exists but the property doesn’t, it still returns undefined, and that's fine!
  • Don’t overuse it. Optional chaining is powerful, but you should still validate your data properly in most cases.

Support my work!