I was looking at some particularly ugly client code recently. I was pairing with a co-worker and recommended we use optional chaining. He asked about support and I actually didn't know, so I wrote this article.
The optional chaining operator allows a check of deep chains in an object without having to verify each step.
Syntax
object?.prop1?.prop2?.prop3
Actual Code
Without Optional Chaining
Yeah, modified a bit.
if (!!data.additionalParams
&& !!data.additionalParams.type
&& data.additionalParams.type === "AlertType") {
console.log('### Alert Notification', data);
const item = data.additionalParams;
// DO MORE HERE
}
An Improvement
This feels awkward to me, as well as difficult to read. Another attempt ...
if (!!data.additionalParams && !!data.additionalParams.type && data.additionalParams.type === "AlertType") {
console.log('### Alert Notification', data);
const item = data.additionalParams;
// DO MORE HERE
}
An Abstraction
Hmmm, much better ... but who wants to scroll to read the if-condition
. Let's extract the condition to a function ...
function hasAdditionalParams(data) {
return (!!data.additionalParams && !!data.additionalParams.type);
}
if ((hasAssitionalParams(data) && data.additionalParams.type === "AlertType") {
console.log('### Alert Notification', data);
const item = data.additionalParams;
// DO MORE HERE
}
OK, shorter ... but still need to scroll horizontally (a bit).
With Optional Chaining
Now, how about optional chaining
if (data?.additionalParams?.type === "AlertType") {
console.log('### Alert Notification', data);
const item = data.additionalParams;
// DO MORE HERE
}
Testing
Will the optional chaining version above work as I expect. I tested this with a simple test in the console ...
const data1 = { additionalParams: { type: 'bob' } };
const data2 = { additionalParams: { type: 'AlertType' } };
const data3 = {};
console.log(data1?.additionalParams?.type === 'AlertType');
// false
console.log(data2?.additionalParams?.type === 'AlertType')
// true
console.log(data3?.additionalParams?.type === 'AlertType')
// false
Conclusion
This is a very cool pattern that's been introduced into JavaScript. Can I use it reliably?
From caniuse.com ... it looks like a very stable addition!