Before we start to understandoptional chaining, we should understandundefined and what the motivation behindoptional chaining is.
undefined
constme={name:"CodeFinity",age:300,}console.log(me.handles);// undefinedWith ourcomposite data types -collections such asobject literals 👆🏽 - if access a 🔑 that doesn't exist we get back a specialprimitive data type,undefined.
Yea, it's a bit weird that JS has its own 'special data type' and even weirder that we have yet anotherprimitive data type,null (we'll deal with that in the next post in this series).
Nevertheless, hopefully at this point you can accept that thehandles is akey that has 'no definition' within the context ofme👆🏽.
At this point, JS is not 'error-ing out' - it's 🙆🏽♂️ withundefined
Now, referencingme 👆🏽 once again, what if we did:console.log(me.handles.twitter)❓
Uncaught TypeError: Cannot read property 'twitter' of undefined
Observations
- Accessing a 🔑 within anobject literal that doesn't exist is 🙆🏽♂️ - it's
undefined. - Accessing a 🔑 onsomething that is
undefinedis 🙅🏽♂️ - it creates an error❗
undefined is its ownprimitive data type. It'snot a collection type. Therefore anytime that we invoke. onundefined, JS is going to have a problem with that. By definition,primitive data types arediscrete values; they cannot hold any 🔑s! That's what that error message is telling us 👆🏽.
Preventing Our Program From Crashing 😑
Referencing again, the attempt to access:me.handles.twitter 👆🏽, withoutoptional chaining, I might have to write my code like this one:
// Referencing 'me' 👆🏽if(me.handles){console.log(me.handles.twitter)}Now, my program will not crash because we will never reach the line:console.log(me.handles.twitter).
Instead, JS will applyimplicit coercion to:me.handles. This just means that since we are usingif, 'under the hood,' JS will look at theundefinedvalue that stems fromme.handles and will 'coerce' it tofalse (it's a 'false-y' value). So, that code inside of the{ after thatif will not run.
Short-Circuit&& Approach
We could also do this by _short circuiting&&:me.handles && console.log(me.handles.twitter).
This time, whenme.handles gets'implicitly coerced tofalse the right-hand sideoperand of&& will never get run 🍦.
Ternary Approach
We could also shorten that code by using aternary:
// Referencing 'me' 👆🏽console.log(me.handles?me.handles.twitter:"");JS would again,implicitly coerceme.handles tofalse and would take the right hand sideoperand of the:operator,"", therebylogging that emptystring.
Use Optional Chaining -?. - to Prevent Our Program From Crashing 🤓
console.log(me.handles?.twitter)
This syntax sort of applies theternary, but in a simpler way. That. after? is the 'optional' part of this.
First, we are asking the a ❓, "Hey, JS, doesme.handles come back as anobject literal?" If so, then go ahead with this next part of mychain. If not,please don't freak out 😱...let's just leave it asundefined and move on.
Examples
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chainingconstadventurer={name:'Alice',cat:{name:'Dinah'}};constdogName=adventurer.dog?.name;console.log(dogName);// expected output: undefinedconsole.log(adventurer.someNonExistentMethod?.());// expected output: undefinedYes, this works formethods also:console.log(adventurer.someNonExistentMethod?.());
Here's another example from that same MDN link (slightly modified):
constcustomer={name:"Carl",details:{age:82,location:"Paradise Falls"// detailed address is unknown}};constcustomerCity=customer.details?.address?.city;From this one, we see that we can chainoptional chaining.
⚠️
I should mention thatoptional chaining is an ES2020 thing. This means that unless you are using something likeBabel as part of your build process, you will probably not be able to use this feature in your code today. For example, a Node.js repl.it will freak out about this. However, Chrome Dev Tool's console can useoptional chaining.
Top comments(0)
For further actions, you may consider blocking this person and/orreporting abuse



