Optional Chaining and Nullish Coalescing
Safely access nested data with ?. and default values with ?? — without the bugs that && and || defaults introduce.
API responses and form state are deeply nested and often incomplete. Before ES2020, developers chained && checks or try/catch blocks to avoid "Cannot read property of undefined." Optional chaining (?.) and nullish coalescing (??) are now the standard — but they solve different problems than || and &&, and mixing them incorrectly still ships bugs to production.
Optional chaining — short-circuit on null/undefined
Optional chaining stops evaluation when it hits null or undefined and returns undefined instead of throwing. It works for property access (obj?.prop), bracket access (obj?.[key]), and method calls (obj?.method?.()). It does not catch missing DOM nodes in invalid HTML — it only guards nullish roots.
Sangam
undefined
undefined
okNullish coalescing — default only for null/undefined
?? returns the right-hand side only when the left is null or undefined — not when it is 0, "", or false. That fixes the classic || bug: const page = query.page || 1 turns page 0 into 1. Use ?? when 0 and empty string are valid values (pagination, user input, numeric counters).
3
0
default
true
falseCombining ?. and ?? in API mappers
Real backend JSON often omits keys entirely. A mapper layer normalizes shape for the UI: read with ?., default with ??, validate types before render. This pattern appears in every AceDevHub page that consumes Fastify API envelopes.
{ id: 7, displayName: 'dev@acedevhub.com', plan: 'free', avatarUrl: null }| Operator | Left is 0 or "" | Left is null/undefined |
|---|---|---|
| a || b | Uses b | Uses b |
| a ?? b | Uses a | Uses b |
| a?.b | Accesses b | Returns undefined |
Optional chaining and nullish coalescing reduce defensive if ladders when mapping API JSON, but they do not validate shape at runtime. TypeScript and Zod still matter for external data. Use ?. ?? together: ?. for safe navigation, ?? for defaults that respect 0 and empty string.
Combining with logical operators
Mixing ?. with && and || requires parentheses — operator precedence still applies. (user?.flags?.beta) ?? false is clearer than user?.flags?.beta || false when false is a valid flag value. When in doubt, assign to a named const and branch explicitly — readability beats one-liner density.
- 1?. stops at null/undefined — returns undefined, no throw
- 2?? defaults only null/undefined — keeps 0, "", false
- 3Combine in API mappers for safe nested reads
- 4Avoid || for numeric and string defaults when falsy is valid
- 5Next lesson: fetch and JSON end-to-end