Can a question mark can save your entire application?😮 :- Guide To Optional Chaining❤🔗❤
Table of contents
Have you ever wondered what would happen to your react application or any front-end application which is dependent on APIs and that API will not give you the data which you're expecting and you try to show that particular properties of that data in your application which is not present in the server response? Wait a minute and think about what will happen. Your application will break🤦♂️. To solve these types of problems you need to add error boundaries to your application. but you can also use some of the modern Javascript methods to prevent and tackle these types of issues. One of the most used features these days in every JS application among developers is optional chaining🔗.
What is Optional Chaining?🔗
Optional Chaining is a type of operator that is introduced in modern javascript. It helps in accessing an object's property or calling an associated function. If the object accessed or function called is null or undefined🤷♀️, it returns undefined instead of throwing an error.
Example:-
const employee = {
name: "Prabadhya Upadhyay",
info: {
empId: "XYZ_124"
}
}
const salaryOfEmployee = employee.salary?.amount
console.log(salaryOfEmployee); // Will not throw Type Error and return undefined
console.log(employee.generateSalary?.()) // Will not throw Type Error and return undefined
//Syntax
obj.val?.prop
obj.val?.[expr]
obj.func?.(args)
Explanation:-
The ?.
operator is like 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.
Usage:-
Handling uncertain Data🐍:- The most common and the biggest advantage of optional chaining is when you're not sure about the data which is coming from API and you're accessing the data properties which is not present in the result data. Let's see how can we tackle this issue by using optional chaining:-
Problem🤔:-
In The below code, we're fetching the employee data and rendering it but some of the employees have provided alternate numbers and some have not because it was an optional field if we will iterate this data we will get a type error🍀 because our code doesn't know which data or property is optional it will just try to access the same alternate number property on every employee.
import './App.css';
function App() {
const data = [
{
name: "Employee1",
info: {
address: "XYZ_Indore_452012",
salary: "10,000",
Contact_Details: {
Contact_Number: "76656832XX",
Alternate_Number: {
status:"yes",
detail:"779854XX"
},
email: "Dummy@employee.com"
}
}
},
{
name: "Employee2",
info: {
address: "XYZ_Mumbai_452012",
salary: "15,000",
Contact_Details: {
Contact_Number: "76656832XX",
Alternate_Number: {
status:"yes",
detail:"779854XX"
},
email: "Dummy@employee.com"
}
}
},
{
name: "Employee3",
info: {
address: "XYZ_Banglore_452012",
salary: "20,000",
Contact_Details: {
Contact_Number: "76656832XX",
email: "Dummy@employee.com"
}
}
}
];
return (
<div className="App">
{data.map((employee, index) => {
return (
<div key={index} style={{ border: "1px solid red" }}>
<p>Name:- {employee.name}</p>
<p>Address:-{employee.info.address}</p>
<p>Salary:-{employee.info.salary}</p>
<p>Email:-{employee.info.Contact_Details.email}</p>
<p>ContactNo:-{employee.info.Contact_Details.Contact_Number}</p>
<p>
Alternate_Contact:-
{employee.info.Contact_Details.Alternate_Number.detail}
</p>
</div>
);
})}
</div>
);
}
export default App;
Error Snap:-
This will just break the whole application.
Solution😀:-
In the below code, you can see that we've added optional chaining using ?. Now it is checking whether the referenced value exists or not if not then it returns undefined rather than throwing an error.
import './App.css';
function App() {
const data = [
{
name: "Employee1",
info: {
address: "XYZ_Indore_452012",
salary: "10,000",
Contact_Details: {
Contact_Number: "76656832XX",
Alternate_Number: {
status:"yes",
detail:"779854XX"
},
email: "Dummy@employee.com"
}
}
},
{
name: "Employee2",
info: {
address: "XYZ_Mumbai_452012",
salary: "15,000",
Contact_Details: {
Contact_Number: "76656832XX",
Alternate_Number: {
status:"yes",
detail:"779854XX"
},
email: "Dummy@employee.com"
}
}
},
{
name: "Employee3",
info: {
address: "XYZ_Banglore_452012",
salary: "20,000",
Contact_Details: {
Contact_Number: "76656832XX",
email: "Dummy@employee.com"
}
}
}
];
return (
<div className="App">
{data.map((employee, index) => {
return (
<div key={index} style={{ border: "1px solid red" }}>
<p>Name:- {employee.name}</p>
<p>Address:-{employee.info.address}</p>
<p>Salary:-{employee.info.salary}</p>
<p>Email:-{employee.info.Contact_Details.email}</p>
<p>ContactNo:-{employee.info.Contact_Details.Contact_Number}</p>
<p>
Alternate_Contact:-
{employee.info.Contact_Details.Alternate_Number?.detail}
</p>
</div>
);
})}
</div>
);
}
export default App;
Solution Snap:-
2.) Usage with null coalescing operator☠:-
Another common usage of optional chaining is when you want to return a default value when your expected property doesn't exist. you can use it with the null coalescing operator to put a default value.
import './App.css';
function App() {
const data = [
{
name: "Employee1",
info: {
address: "XYZ_Indore_452012",
salary: "10,000",
Contact_Details: {
Contact_Number: "76656832XX",
Alternate_Number: {
status:"yes",
detail:"779854XX"
},
email: "Dummy@employee.com"
}
}
},
{
name: "Employee2",
info: {
address: "XYZ_Mumbai_452012",
salary: "15,000",
Contact_Details: {
Contact_Number: "76656832XX",
Alternate_Number: {
status:"yes",
detail:"779854XX"
},
email: "Dummy@employee.com"
}
}
},
{
name: "Employee3",
info: {
address: "XYZ_Banglore_452012",
salary: "20,000",
Contact_Details: {
Contact_Number: "76656832XX",
email: "Dummy@employee.com"
}
}
}
];
return (
<div className="App">
{data.map((employee, index) => {
return (
<div key={index} style={{ border: "1px solid red" }}>
<p>Name:- {employee.name}</p>
<p>Address:-{employee.info.address}</p>
<p>Salary:-{employee.info.salary}</p>
<p>Email:-{employee.info.Contact_Details.email}</p>
<p>ContactNo:-{employee.info.Contact_Details.Contact_Number}</p>
<p>
Alternate_Contact:-
{employee.info.Contact_Details.Alternate_Number?.detail ?? "No Alternate Number"}
</p>
</div>
);
})}
</div>
);
}
export default App;
Explanation🚍:-
In the above code, we're checking if the alternate number is present or not if it is not then we're putting "No Alternate Number" in the field and this is what the null coalescing operator does it checks if the left-hand side value is undefined then it returns the right-hand side value (our value) or vice versa.
Snap:-
3.) Other Use Cases:-
It has some of the sort of other use cases as well let's say if you want to traverse through an object or access its properties you can avoid writing numerous if statements to check whether one property exists then do this & that.
Conclusion:-
Modern Day Javascript is evolving consistently. New features are coming out that are making the language more acceptable among developers. These can be used as best practices in your code to make it look more presentable and avoid the old lengthy and time-consuming practices.
I hope you've enjoyed reading this article. If you've enjoyed please like👍, share🔗 and subscribe for more articles just like this. Until then Thanks a lot for Reading...
Subscribe to my newsletter
Read articles from Prabadhya Upadhyay directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Prabadhya Upadhyay
Prabadhya Upadhyay
I am an aspiring Full Stack Developer. Currently Learning MERN Stack and documenting my Journey here!