Exploring JavaScript’s Optional Chaining (?.): A Safer Way to Access Properties
In modern JavaScript development, it’s common to encounter deeply nested objects — especially when working with complex data from APIs or user input. A typical problem arises when some parts of the object hierarchy are null or undefined, leading to frustrating runtime errors like "Cannot read property of undefined".
Enter Optional Chaining (?.), a feature introduced in ES2020, which provides a concise and safe way to access properties of an object without throwing errors when encountering null or undefined.
Get Mukul Medatwal’s stories in your inbox
Join Medium for free to get updates from this writer.
In this blog, we’ll cover what Optional Chaining is, how it works, and why it’s a game-changer for JavaScript developers.
What is Optional Chaining?
Optional Chaining (?.) allows developers to safely access deeply nested properties, even if an intermediate property is null or undefined. Instead of throwing an error, it simply returns undefined when it encounters a null or undefined value.
The Problem without Optional Chaining
Let’s say we have a deeply nested object:
const user = {
profile: {
name: 'Alice',
address: {
street: '123 Main St'
}
}
};If you want to access user.profile.address.street, it works fine as long as user, profile, and address all exist. But what if profile or address is missing? Without Optional Chaining, you would need to check each property along the way:
if (user && user.profile && user.profile.address) {
console.log(user.profile.address.street);
} else {
console.log('Address not available');
}This pattern can quickly become tedious and error-prone, especially for complex objects.
How Optional Chaining Works
Optional Chaining simplifies the process of checking for null or undefined at each level:
console.log(user?.profile?.address?.street); // Output: '123 Main St'In this case, if any part of the chain (user, profile, or address) is null or undefined, the expression safely returns undefined without throwing an error.
Example with Missing Data
const user = { profile: null };
console.log(user?.profile?.address?.street); // Output: undefined (No error)Here, since user.profile is null, the expression gracefully returns undefined rather than attempting to access address and causing an error.
Key Use Cases for Optional Chaining
Optional Chaining proves especially useful in a variety of scenarios. Let’s explore some of the most common use cases:
1. Accessing Nested Properties
As mentioned above, you can safely access deeply nested properties without writing cumbersome null checks.
const user = { profile: null };
console.log(user?.profile?.address?.city); // Output: undefined2. Calling Optional Methods
Optional Chaining can also be used for safely calling methods that might not exist.
const user = {
profile: {
greet() {
return 'Hello!';
}
}
};
console.log(user?.profile?.greet()); // Output: 'Hello!'
console.log(user?.profile?.nonExistentMethod?.()); // Output: undefined (No error)In the second example, calling nonExistentMethod doesn’t throw an error since the method doesn’t exist; it simply returns undefined.
3. Handling Dynamic Data from APIs
When working with data from external APIs, some fields may be missing. Optional Chaining helps ensure that you’re not trying to access properties that might not exist, preventing runtime errors.
const apiResponse = {
user: {
settings: {
theme: 'dark'
}
}
};
const theme = apiResponse?.user?.settings?.theme ?? 'light'; // Fallback to 'light' if theme is missing
console.log(theme); // Output: 'dark'In this example, if any part of the chain (e.g., user or settings) is missing, the expression returns undefined and the fallback value 'light' is used.
Optional Chaining with Arrays
Optional Chaining also works with arrays to check if an element at a certain index exists.
const users = [{ name: 'Alice' }, null, { name: 'Bob' }];
console.log(users[1]?.name); // Output: undefined (No error)
console.log(users[2]?.name); // Output: 'Bob'Here, users[1] is null, so accessing .name does not throw an error—it simply returns undefined.
Optional Chaining in Function Calls
Another useful feature is applying Optional Chaining to function calls, where the function itself might not be defined:
const user = {
profile: {
sayHello: () => 'Hello, world!'
}
};
console.log(user?.profile?.sayHello?.()); // Output: 'Hello, world!'
console.log(user?.profile?.nonExistentFunction?.()); // Output: undefined (No error)If the function doesn’t exist, the expression will not attempt to call it and will return undefined instead.
Optional Chaining Combined with Nullish Coalescing (??)
Optional Chaining can be even more powerful when used alongside the Nullish Coalescing Operator (??). This combination allows you to provide a fallback value when the result of an Optional Chaining expression is undefined.
const user = { profile: null };
const street = user?.profile?.address?.street ?? 'No street provided';
console.log(street); // Output: 'No street provided'Conclusion
The Optional Chaining (?.) operator is a significant addition to JavaScript that helps developers write cleaner, safer code by eliminating the need for repetitive null checks. It enhances the readability and maintainability of your code, particularly when working with nested objects, optional methods, or data from external sources.
By embracing Optional Chaining, you can streamline your error handling and focus more on the logic of your application without worrying about null reference errors.
Happy coding!








