Have you ever tried to access a property in JavaScript and got an error because the object was undefined or null? That’s where optional chaining (?.) comes to the rescue!
What is Optional Chaining?
Optional chaining (?.) is a feature in JavaScript that lets you safely access deeply nested properties without worrying about errors. If a property doesn’t exist, it simply returns undefined instead of throwing an error.
Why is it Useful?
In real-world applications, data isn’t always structured the way we expect. Sometimes an API response might not include all the expected fields, or a user might leave some form fields empty. Instead of writing long checks, optional chaining makes things simple.
Example Without Optional Chaining
const user = { name: "Ali" };
console.log(user.address.city); // ❌ Error: Cannot read properties of undefinedSince user doesn’t have an address, JavaScript throws an error.
Example With Optional Chaining
console.log(user?.address?.city); // ✅ undefined (No error)Now, instead of crashing, JavaScript safely returns undefined.
Where Can You Use It?
Accessing Object Properties
const person = { profile: { name: "John" } };
console.log(person?.profile?.name); // John
console.log(person?.profile?.age); // undefined (No error)Calling Methods Safely
Sometimes, you may need to call a method on an object, but you’re unsure if the method exists. Without optional chaining, calling a missing method causes an error. You just need to add ?. between the method name and the parentheses.
const logger = { log: (msg) => console.log(msg) };
logger.log?.("Hello!"); // Works fine
logger.debug?.("Test"); // No error, just does nothingThe ?. ensures both of these things before calling the method:
- The method exists.
- It is actually a function (not undefined or null).
Working with Arrays
const employees = [
{ name: "John", contact: { email: "john@example.com" } },
{ name: "Jane" }, // No contact info
];
console.log(employees[1]?.contact?.email || "No email available"); // No email availableWhy? Prevents trying to access .contact.email on an undefined object.
Handling API Data
APIs often return deeply nested objects, and not all fields are guaranteed to exist. Instead of manually checking each level, optional chaining makes access safer.
fetch("https://api.example.com/user/123")
.then((res) => res.json())
.then((data) => {
console.log(data?.profile?.address?.city || "City not available");
});Why? Prevents runtime errors if profile or address is undefined or null.
Accessing DOM Elements Safely
If a DOM element might not exist, optional chaining prevents errors.
document.querySelector(".non-existent")?.classList.add("active");Why? Without optional chaining, this would throw a TypeError.
Conclusion
Optional chaining makes JavaScript code cleaner, safer, and easier to read. Instead of writing long checks, you can use ?. to prevent errors and keep your code running smoothly. 🚀