This tutorials explains about fixing an error , an feature of Optional Chaining Operator.
TypeError: Cannot read property ‘’ of undefined
javascript nested object undefined or null check
A nested object is an object nested inside an object with a deep level. Each object contains properties. Let’s see an example to check nullish values against deeply nested properties in the current javascript implementation.
const employee = {
name: 'Franc',
department: {
name: 'sales'
}
};
const name = employee.name;
console.log(name); // Franc
const department = employee.department;
console.log(department);// {name:'sales'}
const departmentName = employee.department.name;
console.log(departmentName); //sales
console.log(employee.salary) //undefined
console.log(employee.department.supervisor) // undefined
In the above example, Create an object with nested properties.
accessing object with valid properties (name, department, and department. name) returning valid values.
Accessing non existing properties (employee.salary, employee.department.supervisor) in objects returns `undefined'.
Accessing nested properties on an undefined object () throws an error -TypeError: Cannot read property 'name' of undefined
as seen in the below example.
console.log(employee.department.supervisor.name)
we have to handle null or undefined values using if-else conditional expression and fallback to else block to avoid these errors.
if ((employee)
&& (employee.department)
&& (employee.department.supervisor)
&& (employee.department.supervisor.name)) {
console.log(employee.department.supervisor.name)
}
else {
console.log('department supervisor name not found');
}
And output is
department supervisor name not found
Code looks not simple and needs to write a lot of code and is difficult to readability to handle deeply nested objects with more levels.
The same can be rewritten using the ternary operator.
const deptname =
(employee
? (employee.department
? (employee.department.supervisor
? employee.department.supervisor.name
: undefined)
: undefined)
: undefined);
console.log(deptname)// undefined
With ES11, The null and undefined handling is simplified by introducing the Optional Chaining Operator
.
Let’s look into a new feature in ES11
.
Es11 features- Optional Chaining Operator
Optional Chaining operator is the latest feature introduced with ‘ES2020’ to the latest javascript.
and its symbol is ?.
ie single question mark and dot.
This operator allows finding the nested object properties without checking the reference of each nested object property.
This operator enables to return of undefined or fallback value if any reference is nullish
values - null
or undefined
.
Advantages
- This looks simple and has less coding
- Human readability to avoid error-prone
- useful to avoid errors.
This will be useful for default to fallback value when deeply object properties are null or undefined.
It is a Short circuit operator
that applies two expressions, and returns its value of
- right-hand expression is not processed when the left-hand expression evaluated is
null
orundefined
. - left-hand operand value when the left-hand operand is not
null
orundefined
Syntax
Object?.property
Object?.[expresson]
array?.[index]
function?.(args)
The syntax contains question marks with dot operators. There are many variations of using the Optional Chaining operator.
- Object?.property - check Static property
- Object?.[expresson] - Check Dynamic property
- array?.[index] - Check array index values
- function?.(args) - Checking in function calls
For example, given a deeply nested object (employe.department.name), check for null or undefined values for the name property.
let departmentName=employe.department && employe.department.name;
Rewriting using optional chain operator
let deparmentName=employe.department?.name
Variables are added to the hash symbol to make it for private use in a class. Syntax
#variable
Let’s see an example.
const result1 = null ?? "default1";
const result2 = "" ?? "default2";
const result2 = 11 ?? 0;
console.log(result1); // default1
console.log(result2); // default2, Empty string is not equal to null or undefined
console.log(result2); // 11
Optional Chaining in Typescript example
Optional Chaining operator introduced in Typescript 3.7
language.
This will be useful for checking the response from consuming API calls Consider API calls that return the nested deep response object.
const result = response.employe.department.id;
if an employee or department is null or undefined, It throws an error TypeError: Cannot read property ’employe’ of undefined. To avoid these errors, have to validation check as per below.
let id;
if (response.employe && response.employe.department) {
id = response.employe.department.id;
}else{
id="Id not found"
}
so id always has value either valid value or default fallback value. To avoid this length code check, the nullish coalescing operator, and optional chaining simplified this and error-prone.
const id = response.employe?.department?.id ?? "Id not found.";
compare with Ternary operator
We already have the Ternary operator - ?
.
Optional Chaning | Ternary Operator | description |
---|---|---|
object?.value1 | object == null ? undefined : object?.value1 | if object is null or undefined, returns undefined,else returns object.value1 |
object?.[name] | object == null ? undefined : object[name] | returns object[name] if nullish else undefined |
object?.function() | object == null ? undefined : object.function() | calls object.function() if not nullish,else return undefined, error if not function |
Option chaining properties can be used in short-circuit
, long short-circuit
, and stacking
operations.
Browser Support
This feature supports the following browser versions.
- Chrome 80+
- Firefox’s latest version
- Safari’s latest version
- Babel plugin
Babel plugin-proposal-optional-chaining
To install this feature nodejs applications, Please add plugin-proposal-optional-chaining as devDependencies.
npm install --save-dev @babel/plugin-proposal-optional-chaining
configure .babelrc file by adding plugins entry as follow
{
"plugins": ["@babel/plugin-proposal-optional-chaining"]
}