Write Safer JavaScript with Optional Chaining (?.)

Write Safer JavaScript with Optional Chaining (?.)
Photo by Nathan Dumlao / Unsplash

In the ever-evolving world of JavaScript, writing robust, error-resistant code is crucial — especially when dealing with deeply nested objects, API responses, or user-generated data. One of the most underrated but powerful features that can help us achieve this is optional chaining (?.).

Let’s unpack this modern feature, explore why and how to use it effectively, and cover some real-world examples and caveats.


🧩 The Problem: Deep Property Access Can Break Things

If you’ve ever written something like this:

const city = user.profile.address.city;

…you’ve probably run into this error at some point:

Uncaught TypeError: Cannot read properties of undefined

That’s because if any part of the chain (profile, address, or even user) is undefined or null, the whole expression throws an error.

To avoid this, many developers resorted to defensive checks:

const city =
  user &&
  user.profile &&
  user.profile.address &&
  user.profile.address.city;

🤮 Yuck. It's messy, hard to read, and easy to get wrong.


✅ The Solution: Optional Chaining

With the introduction of optional chaining (?.), you can now write:

const city = user?.profile?.address?.city;

This returns:

  • The value of city if it exists, or
  • undefined if any part of the chain is null or undefined.

No errors. No verbose checking. Just clean, safe, modern code.


🔍 How It Works

  • user?.profile checks if user is not null or undefined. If so, it accesses profile.
  • If user is undefined, the expression stops there and returns undefinedno crash.
  • You can chain this for as many levels as needed.

🧪 Use Cases in the Real World

1. API Responses

const fullName = apiResponse?.data?.user?.profile?.fullName ?? 'Anonymous';

Here, ?? is the nullish coalescing operator, providing a fallback only when the result is null or undefined.

2. DOM Access

const title = document.querySelector('.page-title')?.textContent;

If the element doesn’t exist, it simply returns undefined — no error thrown.

3. Optional Function Calls

user?.sendMessage?.('Hello');

If sendMessage is not a function (or doesn’t exist), it won’t be called.


⚠️ Important Considerations

  • Not supported in older browsers like IE11. Use Babel or modern bundlers to transpile if needed.
  • Only prevents errors from null or undefined — it does not protect against other types like strings, booleans, etc.
  • Don't overuse it. If you're always checking deep paths, it might indicate bad data structure design or a need for validation earlier in your logic.

🧼 Bonus Tip: Combine with ?? for Fallbacks

const theme = user?.settings?.theme ?? 'light';

Here, if theme is missing, we gracefully fallback to 'light'.

This is better than using ||, because:

user?.settings?.theme || 'light'; // will use 'light' even if theme is ''

🏁 Finally

Optional chaining is more than just syntactic sugar — it represents a shift toward safer and more expressive JavaScript. It allows us to fail gracefully instead of throwing errors that crash our applications.

So the next time you're reaching deep into an object, ask yourself:

"Should I be using optional chaining here?"

Probably yes.


🔖 Summary

Feature Benefit
obj?.prop Prevents crash if obj is null or undefined
obj?.[index] Safe access for array-style keys
func?.() Safe function invocation
Combine with ?? Provide fallback values safely

Support Us