- Array() find
- -- operator
- -= operator
- ++ operator
- += operator
- Accessing and setting content
- AND operator
- Array concat() method
- Array indexOf()
- Array length
- Array pop()
- Array shift
- Array slice() method
- Arrays
- Arrow function
- Async await
- Booleans
- Braces
- Callback function
- Calling the function
- Class
- Closure
- Code block
- Comment
- Conditions
- Console
- const
- Constructor
- Creating a p element
- Data types
- Date getTime()
- Destructuring
- DOM
- Else
- Else if
- Enum
- Environment
- Equals operator
- Error Handling
- ES6
- Event listener method
- Event loop
- Events
- Export statement
- Extends
- Fetch API
- Filter
- For loop
- forEach()
- Function
- Function bind()
- Function name
- Greater than
- Head element
- Hoisting
- If statement
- Import statement
- includes()
- Infinity property
- isNaN function
- Iterator
- JSON
- Less than
- Let
- Local storage
- Map
- Methods
- Module
- Modulo operator
- Node.js
- null
- Numbers
- Object
- Object.keys()
- Optional chaining
- Overriding methods
- Parameters
- Promises
- Prototype
- Random
- Reduce
- Regex
- Regular expressions
- Removing an element
- Replace
- Scope
- Session storage
- setInterval
- setTimeout() method
- Sleep() function
- Sort
- Splice
- Spread operator
- String
- String concat()
- String indexOf()
- String slice() method
- Substring
- Switch statement
- Template literals
- Ternary operator
- throw Statement
- Title
- Try catch
- Type conversion
- undefined
- var
- void Operator
- What is JavaScript?
- While loop
JAVASCRIPT
JavaScript Optional Chaining: Syntax, Usage, and Examples
Optional chaining (?.) lets you safely access properties and call methods on values that might be null or undefined. Instead of crashing with an error, your code returns undefined and keeps going.
How to Use Optional Chaining
Optional chaining looks like a tiny question mark with a dot: ?.. You place it right before the property, index, or function call you want to access.
Learn JavaScript on Mimo
Basic property access
Use it when a property might not exist.
const user = {
name:"Lea",
profile: {
city:"Vienna"
}
};
console.log(user.profile?.city);// "Vienna"
console.log(user.settings?.theme);// undefined
Without optional chaining, user.settings.theme would throw an error because settings doesn’t exist.
Optional chaining with nested objects
This is where it shines. You can chain multiple levels safely.
const order = {
id:"A-204",
delivery: {
address: {
street:"Main Street 12"
}
}
};
console.log(order.delivery?.address?.street);// "Main Street 12"
console.log(order.pickup?.location?.name);// undefined
Optional chaining with arrays
Use optional chaining when indexing into an array that might not exist yet.
const playlist = {
songs: ["Intro","Moonlight","Finale"]
};
console.log(playlist.songs?.[1]);// "Moonlight"
console.log(playlist.tracks?.[0]);// undefined
Notice the syntax: ?.[index].
Optional chaining with function calls
You can also call a method only if it exists.
const settings = {
onSave:() =>console.log("Saved!")
};
settings.onSave?.();// "Saved!"
settings.onCancel?.();// nothing happens, returns undefined
This is perfect for “maybe callbacks”, like event handlers or plugin hooks.
Optional chaining with dynamic keys
Sometimes you don’t know the property name ahead of time.
const profile = {
name:"Tariq",
socials: {
github:"tariq-dev"
}
};
const platform ="twitter";
console.log(profile.socials?.[platform]);// undefined
console.log(profile.socials?.["github"]);// "tariq-dev"
When to Use Optional Chaining
Optional chaining is like putting bumpers on your code. You still aim straight, but you won’t crash the moment something is missing.
Here are situations where it’s genuinely useful.
1) Working with API data that may have missing fields
APIs change, fields can be optional, and users can have incomplete profiles. Optional chaining helps you display what’s available without writing a dozen checks.
2) Handling user-generated content
Users can leave empty fields, skip steps, or delete parts of their data. Optional chaining keeps UI logic clean when you read values from forms or profile objects.
3) Calling optional callbacks or plugin functions
Many systems let you pass an optional function like onSuccess or onError. Optional chaining lets you call it only when it exists.
4) Rendering UI components based on nested data
You might read user.profile.avatar.url in a UI, but some users won’t have an avatar. Optional chaining avoids UI crashes and keeps rendering logic simpler.
5) Accessing deeply nested config values
Apps often store settings in nested objects, especially when defaults and overrides get merged. Optional chaining makes these lookups safer.
Examples of Optional Chaining
Example 1: Safely showing profile information
Imagine you’re building a small profile card. Some users have a bio, some don’t.
const user = {
name:"Mina",
profile: {
bio:"Frontend dev who loves clean CSS."
}
};
const bioText = user.profile?.bio ??"No bio yet.";
console.log(bioText);
// "Frontend dev who loves clean CSS."
If profile or bio is missing, the ?? fallback keeps the output friendly.
Example 2: Reading nested product data from an API
Product listings can get messy. Sometimes a product has no images.
const product = {
title:"Wireless Keyboard",
media: {
images: [
{url:"https://example.com/keyboard.png" }
]
}
};
const firstImageUrl = product.media?.images?.[0]?.url;
console.log(firstImageUrl);
// "https://example.com/keyboard.png"
If any part is missing, you get undefined, which you can handle with a fallback image.
Example 3: Calling an optional event handler
Let’s say a component accepts an optional onClose callback.
const modalProps = {
title:"Terms",
onClose:null
};
modalProps.onClose?.();// does nothing
No if statement needed.
Example 4: Working with arrays that might be empty
Sometimes you want the first item, but the list could be empty.
const messages = [];
const latestMessage = messages?.[0]?.text;
console.log(latestMessage);
// undefined
Optional chaining protects the indexing, and the ?.text protects the property access.
Example 5: Using optional chaining in a loop
Optional chaining helps when iterating through objects that have optional nested data.
const users = [
{name:"Ana",contact: {email:"ana@mail.com" } },
{name:"Bo",contact:null },
{name:"Chris" }
];
users.forEach((person) => {
const email = person.contact?.email ??"No email";
console.log(`${person.name}:${email}`);
});
Output:
Ana: ana@mail.com
Bo: No email
Chris: No email
No crashes, no extra checks, still readable.
Learn More About Optional Chaining
Optional chaining vs classic checks
Before optional chaining, you’d often see code like this:
const city = user && user.profile && user.profile.address && user.profile.address.city;
It works, but it’s hard to read and easy to mess up.
Optional chaining turns that into:
const city = user.profile?.address?.city;
Same idea, cleaner result.
Optional chaining vs try...catch
Some developers used try...catch to avoid crashes during nested lookups. That’s heavy for something this common, and it can hide real bugs.
Optional chaining is meant for “missing data is normal” cases, not for ignoring real problems.
Optional chaining and the nullish coalescing operator (??)
Optional chaining often pairs nicely with ??.
?.safely accesses a value??gives a fallback only when the value isnullorundefined
Example:
const theme = user.settings?.theme ??"light";
If the theme is missing, you get "light".
If the theme is "dark", you keep it.
This is different from ||, which treats empty strings and 0 as falsey:
const name = user.profile?.nickname ||"Anonymous";
If nickname is "", that code would pick "Anonymous", even though an empty string might be valid.
Optional chaining does not stop all errors
Optional chaining helps with missing values, but it won’t fix incorrect types.
For example, this still breaks:
const user = {profile:"not an object" };
// This fails because profile is a string, not an object with a city
console.log(user.profile?.city);
Optional chaining checks for null or undefined, not “wrong shape”.
Optional chaining in assignments (what you can’t do)
Optional chaining is for reading or calling, not for writing.
This won’t work:
// ❌ Syntax error
// user.profile?.city = "Berlin";
Instead, update safely with checks:
if (user.profile) {
user.profile.city ="Berlin";
}
A practical mental shortcut
Optional chaining is perfect when your code would naturally say:
“If this exists, grab it. If not, no big deal.”
That mindset keeps your programs calmer, especially when dealing with real-world data.
Summary
Optional chaining (?.) is a safe way to access deeply nested properties, array items, and optional functions in JavaScript. It prevents crashes when something is missing and pairs nicely with ?? for clean fallback values. Use it for API data, user profiles, UI rendering, and optional callbacks, anywhere missing fields are normal.
Join 35M+ people learning for free on Mimo
4.8 out of 5 across 1M+ reviews
Check us out on Apple AppStore, Google Play Store, and Trustpilot