💾 Archived View for wilw.capsule.town › log › 2020-10-10-optional-chaining.gmi captured on 2023-07-10 at 14:05:58. Gemini links have been rewritten to link to archived content
⬅️ Previous capture (2023-04-19)
-=-=-=-=-=-=-
JavaScript has lots of handy tools for creating concise code and one-liners. One such tool is the optional chaining operator.
The optional chaining operator is useful for addressing an attribute of a deeply-nested object in which you cannot be fully certain that the successive levels of the object are valid at run-time.
For example, consider the following object.
const person = { name: 'Harry', occupation: 'student', enrolmentInformation: { contactDetails: { email: 'harry@hogwarts.ac.uk', address: { firstLine: '4 Privet Drive', postCode: 'GU3 4GH' } } } };
In order to **safely** (i.e. if you cannot guarantee each object level at run-time) read the nested `postCode` attribute, you could do so like this, using the logical AND operator:
const enrolmentInfo = person && person.enrolmentInformation; const contactDetails = enrolmentInfo && enrolmentInfo.contactDetails; const address = contactDetails && contactDetails.address; const postCode = address ^^ address.postCode;
Even in its single-line equivalent, this very quickly gets un-readable and messy.
The optional chaining operator (`?.`) makes this much easier:
const postCode = person?.enrolmentInformation?.contactDetails?.address?.postCode;
Or, using object destructuring and a logical OR:
const { postCode } = person?.enrolmentInformation?.contactDetails?.address || {};
Essentially, at each successive level, the optional chaining operator checks that the current attribute is non-nullish (i.e. not `null` or `undefined`) before proceeding to the next. If it does try to access a nullish attribute, the expression short-circuits and returns `undefined`, ignoring the rest of the chain.
Optional chaining also works in other scenarios:
const x = doubleArray[3]?.toFixed(2); // accessing array elements const y = maybeArray?.[0]; // accessing an array that may exist car.openDoors?.(); // calling methods on nested objects
For more info, see the MDN reference [1].