Skip to main content

How to Resolve "TypeError: Cannot read properties of undefined" Error in JavaScript

The TypeError: Cannot read properties of undefined is one of the most common errors in JavaScript. It occurs when you try to access a property or call a method on a variable that holds the value undefined. This means you expected an object or an array, but you got nothing.

This guide will break down the common causes of this error, from working with uninitialized variables and non-existent object properties to accessing DOM elements that haven't been loaded yet. You will learn the definitive, modern solutions for preventing this error, including optional chaining (?.) and providing fallback values, to make your code more robust and error-free.

Understanding the Root Cause: What is undefined?

In JavaScript, a variable has the value undefined in several situations:

  • It has been declared but not yet assigned a value.
  • It is a function parameter that was not provided when the function was called.
  • It is the return value of a function that doesn't explicitly return anything.
  • You are trying to access an object property or array element that does not exist.

The error occurs when you try to chain another property access onto something that is already undefined.

For example, here JavaScript stops because it can not get the name property from undefined:

let user; // user is declared but not assigned a value, so it is undefined

// ⛔️ TypeError: Cannot read properties of undefined (reading 'name')
console.log(user.name);

Solution 1 (Best Practice): Safe Property Access with Optional Chaining (?.)

The optional chaining operator (?.) is the modern and most elegant solution to this problem. It allows you to safely attempt to access a property deep within a chain of objects without causing an error.

If any part of the chain is null or undefined, the expression short-circuits and immediately returns undefined instead of throwing an error.

Example of code with error:

const person = {
// name property is missing
age: 30
};

// ⛔️ TypeError: Cannot read properties of undefined (reading 'first')
console.log(person.name.first);

The Solution with Optional Chaining

const person = {
age: 30
};

// Use ?. to safely access the 'name' property
const firstName = person.name?.first;

// Output: No error is thrown. The result is just undefined.
console.log(firstName); // Output: undefined

Solution 2: Providing a Default Value with Nullish Coalescing (??)

Often, you don't just want to avoid an error; you want to provide a sensible fallback or default value. You can combine optional chaining (?.) with the nullish coalescing operator (??).

The ?? operator checks if the value on its left is null or undefined and, if so, returns the value on its right.

Example of code with problems:

let user; // undefined

// ⛔️ TypeError: Cannot read properties of undefined (reading 'toUpperCase')
const username = user.name.toUpperCase();

The Solution with a Fallback Value:

let user; // undefined

// Safely access user.name, and if it's null/undefined, use 'Guest'
const username = user?.name ?? 'Guest';

console.log(username); // Output: "Guest"

Common Scenarios and How to Fix Them

Accessing a Non-Existent Object Property

This happens when you expect an object to have a certain structure, but it's missing.

Example of error:

function printStreet(person) {
// ⛔️ TypeError if person.address is undefined
console.log(person.address.street);
}

Correct code:

function printStreet(person) {
// Safely access the nested property.
const street = person?.address?.street ?? 'Address not available';
console.log(street);
}

printStreet({ name: 'John' }); // Output: Address not available

Accessing a Non-Existent Array Element

Accessing an array index that is out of bounds returns undefined.

Example of error:

const fruits = ["apple", "banana"];

// ⛔️ TypeError: fruits[2] is undefined, cannot read 'toUpperCase'
console.log(fruits[2].toUpperCase());

Correct code:

const fruits = ["apple", "banana"];

// Safely access the element at index 2 before calling a method on it.
const thirdFruit = fruits[2]?.toUpperCase() ?? 'No third fruit';

console.log(thirdFruit); // Output: "No third fruit"

Accessing a DOM Element That Doesn't Exist

This is a very common cause of the error in front-end JavaScript. Your code runs, but the HTML element it's looking for isn't on the page.

Example of error:

// ⛔️ TypeError if no element has the ID 'main-title'
const title = document.getElementById('main-title');
// title is null here, which also causes the error
console.log(title.innerText);

Correct code: always check if the DOM element was found before you try to use it.

const title = document.getElementById('main-title');

// Safely access the innerText property only if title is not null.
console.log(title?.innerText); // Output: undefined (no error)

The DOM Isn't Ready: Incorrect Script Placement

A related DOM issue is running your JavaScript before the HTML elements have been parsed by the browser.

Example of error: If your <script> tag is in the <head>, it will run before the <body> is loaded.

<!DOCTYPE html>
<html>
<head>
<title>My Page</title>
<script src="app.js"></script> <!-- Runs too early! -->
</head>
<body>
<div id="app"></div>
</body>
</html>

Your app.js will not be able to find the #app div, resulting in a Cannot read properties of null error.

Correct code: Always place your <script> tags at the end of the <body> tag, or use the defer attribute.

  ...
<body>
<div id="app"></div>
<script src="app.js" defer></script> <!-- defer is also a great option -->
</body>
</html>

Conclusion

The "Cannot read properties of undefined" error is a signal that your code is making an incorrect assumption about the state of a variable.

To write robust, error-free code:

  • Use optional chaining (?.) as your first line of defense to safely access properties that might not exist.
  • Combine optional chaining with the nullish coalescing operator (??) to provide sensible default values.
  • Always check that a DOM element exists after a query before you try to manipulate it.
  • Ensure your <script> tags are loaded at the correct time, either at the end of the <body> or with the defer attribute.