Optional chaining (?.)
Optional chaining operator (?.) permits reading the value of a property located deep within a chain of connected objects without having to expressly validate that each reference in the chain is valid. The `?.` operator functions similarly to the `.` chaining operator, except that instead of causing an error if a reference is nullish (null or undefined), the expression short-circuits with a return value of undefined. When used with function calls, it returns undefined if the given function does not exist.
The Problem 🤷🏻♀️
An object can have a very different nested structure of objects.
- Fetching remote JSON data
- Using configuration objects
- Having optional properties
Working with data in JavaScript frequently involves situations where you aren’t sure that something exists. For example, imagine getting a JSON response from a weather API.
{ "data": { "temperature": { "current": 68, "high": 79, "low": 45 }, "averageWindSpeed": 8 }}
You can go through each level of the object to get the high temperature. ⛅️
The value of response.data
, response.data.temperature
are confirmed to be non-null before accessing the value of response.data.temperature.current
. This prevents the error that would occur if you simply accessed response.data.temperature.current
directly without testing response.data && response.data.temperature
const highTemperature = response.data && response.data.temperature && response.data.temperature.current;
With the optional chaining operator(?.) you don't have to explicitly test and short-circuit based on the state of response.data && response.data.temperature
before trying to access response.data.temperature.current
.
If response.data && response.data.temperature
are null or undefined, the expression automatically short-circuits, returning undefined.
const highTemperature = response.data?.temperature?.current;
By using the ?.
operator instead of just .
, JavaScript knows to implicitly check to be sure response.data && response.data.temperature
are not null or undefined before attempting to access response.data.temperature.current
Optional chaining not valid on the left-hand side of an assignment
let object = {};object?.property = 1; // Uncaught SyntaxError: Invalid left-hand side in assignment
Relationship with the optional chaining operator (?.
)
The nullish coalescing operator treats undefined
and null
as specific values and so does the optional chaining operator (?.
) which is useful to access a property of an object which may be null
or undefined
.
let foo = { someFooProp: "hi" };
console.log(foo.someFooProp?.toUpperCase()); // "HI"console.log(foo.someBarProp?.toUpperCase()); // undefined
Other cases: ?.()
, ?.[]
The optional chaining ?.
is not an operator, but a special syntax construct, that also works with functions and square brackets.
let user1 = { admin() { alert("I am admin"); }}
let user2 = {};user1.admin?.(); // I am adminuser2.admin?.();
Use ?.
with delete ␡:
delete user?.name; // delete user.name if user exists
Few Scenario which needs to taken care of:
- The variable before
?.
must be declared
If there’s no variable user at all, then user?.anything
triggers an error:
// ReferenceError: user is not defineduser?.address;
There must be let/const/var user. The optional chaining works only for declared variables.
- Use
?.
for safe reading and deleting, but not writing
The optional chaining ?. has no use at the left side of an assignment:
// the idea of the code below is to write user.name, if user existsuser?.name = "John"; // Error, doesn't work// because it evaluates to undefined = "John"
Summary 📝
The ?.
syntax has three forms:
obj?.prop
– returnsobj.prop
ifobj
exists, otherwiseundefined
.obj?.[prop]
– returnsobj[prop]
ifobj
exists, otherwiseundefined
.obj?.method()
– callsobj.method()
ifobj
exists, otherwise returnsundefined
.
Reference 🧐
Thanks for reading the article ❤️
I hope you get to learn something new from this article. If you have any question please reach out to me on @suprabhasupi 😋