Optional Chaining (?.)

🧩 1. What Is Optional Chaining?

Optional chaining (?.) lets you safely access nested object properties
without causing an error if something in the chain is null or undefined.

👉 It returns undefined instead of throwing an error.


🧱 The Problem (Without Optional Chaining)

const user = {};
console.log(user.profile.name); // ❌ TypeError: Cannot read properties of undefined

Here, user.profile is undefined,
so trying to access .name crashes the code.


✅ The Solution (With Optional Chaining)

const user = {};
console.log(user.profile?.name); // ✅ undefined (no error)

If profile doesn’t exist, the expression simply stops and returns undefined.


🧠 2. Basic Syntax

object?.property
object?.[key]
object?.method?.()

You can use it with:

  • Object properties
  • Dynamic keys
  • Methods/functions

🧩 Example 1 — Object Property

const user = { info: { name: "Alice" } };

console.log(user.info?.name);     // "Alice"
console.log(user.profile?.name);  // undefined (no error)

🧩 Example 2 — Array Index or Dynamic Key

const data = { items: ["A", "B"] };

console.log(data.items?.[0]);   // "A"
console.log(data.other?.[0]);   // undefined

🧩 Example 3 — Method Calls

const user = {
  greet() {
    return "Hello!";
  },
};

console.log(user.greet?.());      // "Hello!"
console.log(user.sayBye?.());     // undefined (no crash)

🧩 Example 4 — Nested Access

Without optional chaining:

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

With optional chaining:

const city = user?.address?.city;

✅ Much cleaner and more readable.


⚡ 3. Combining with Nullish Coalescing (??)

You can combine ?. with ?? (another ES2020 feature)
to provide default values when something is missing.

const user = {};
const city = user?.address?.city ?? "Unknown";
console.log(city); // "Unknown"

✅ Returns "Unknown" instead of crashing or showing undefined.


🧩 4. Real-World Example

Example: API Response

const response = {
  user: {
    profile: { name: "Sarah" },
  },
};

// Traditional way (unsafe)
console.log(response.user.profile.name); // Works
// console.log(response.account.details.id); // ❌ crash

// Safe way
console.log(response.account?.details?.id); // ✅ undefined

✅ Helps when working with APIs or user input where data may be missing.


🚨 5. What It Can’t Do

❌ You can’t use it on the left-hand side of an assignment:

user?.name = "Alice"; // SyntaxError ❌

❌ It only checks for null or undefined, not falsy values like 0 or "".


🧠 6. Quick Comparison

Without Optional ChainingWith Optional Chaining
user && user.address && user.address.cityuser?.address?.city
data && data.items && data.items[0]data?.items?.[0]
obj && obj.method && obj.method()obj.method?.()

✨ 7. Summary

ConceptDescriptionExampleResult
?.Safe property accessuser?.nameReturns undefined if missing
?.[]Safe dynamic key accessuser?.[key]Returns undefined if missing
?.()Safe method calluser.method?.()Calls only if method exists

💡 8. Practical Tip

Optional chaining is best for:

  • API responses with optional fields
  • Deeply nested data (e.g., user?.profile?.settings?.theme)
  • Avoiding repetitive if or && checks

Leave a Reply