I was surprised by the following behaviour:
const a = {};
a?.b.c; // throws TypeError: Cannot read properties of undefined (reading 'c')
My intention was to use this expression for when a
optionally contains b
, but if b
is present it is expected to contain c
. I had expected the expression a?.b.c
to evaluate to undefined
, and not throw. What expression should I have used?
I did not use a?.b?.c
because I wanted it to throw if b
did not contain c
.
2
Answers
Edit: The code doesn’t work as you expected, you will need the following
In your code, the null coalescing operator prevents the TypeError and returns a null when you try to call "a?.b", the null is then passed to the next field accessor as "(null).c" which throws an error.
You need the question mark on both a and b to avoid the excecption
In JavaScript, the optional chaining operator (
?.
) stops the evaluation and returnsundefined
as soon as it encounters an undefined or null value in the chain. In your original codea?.b.c
, ifa
is undefined, it stops ata?.b
and returnsundefined
. However, when you try to access propertyc
onundefined
, it throws aTypeError
.You need to handle the scenario where either
a
is undefined orb
is undefined, you can achieve this by using conditional statements or a default value. Here are three alternatives:Using Optional Chaining:
Using Conditional Statements:
Using Default Value + Optional Chaining:
In all cases, if any part of the chain is undefined, the result will be
undefined
. The third approach uses the nullish coalescing operator (??
) to explicitly check fornull
orundefined
and provide a default value.