Back to blog

How to Fix Cannot Read Properties of Undefined in JavaScript

If you write JavaScript or TypeScript, you have undoubtedly encountered this runtime crash: "TypeError: Cannot read properties of undefined (reading '...')" (or its legacy browser equivalent: "Cannot read property '...' of undefined").

This is JavaScript's version of a Null Pointer Exception. It happens when you attempt to access a sub-property or execute a method on a variable that currently evaluates to undefined or null.

In this guide, we will analyze why this error occurs, look at common code triggers (like async API delay renders), and master defensive coding patterns to prevent it.

The Cause: Accessing Properties on Empty Variables

In JavaScript, variables are initialized as undefined if they are declared without a value. Additionally, APIs frequently return null to denote the absence of data.

null and undefined are primitive types that possess no properties or methods. If you write:

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

The JavaScript compiler throws an error and halts execution immediately, freezing your frontend UI or crashing your Node.js backend handler.

Common Code Scenarios

Let's look at the three most common situations where this error happens:

Scenario 1: Unsynchronized Asynchronous API Fetches

When your component renders, it initializes state to empty. If your render layout attempts to read deep nested objects before the fetch completes, it crashes:

// INSECURE: If user data is still loading (null), accessing user.profile triggers a crash
export function UserWidget({ userId }) {
  const [user, setUser] = useState(null);

  useEffect(() => {
    fetchUser(userId).then(setUser);
  }, [userId]);

  return (
    <div>
      <img src={user.profile.avatar} alt="Avatar" />
    </div>
  );
}

Scenario 2: Array Out-of-Bounds Queries

Attempting to find an object inside an array, and immediately reading properties on the output without checking if an item was found:

const users = [{ id: 1, name: 'Alex' }];
const match = users.find(u => u.id === 2); // returns undefined

// INSECURE: Crashes because match is undefined
console.log(match.name);

Defensive Coding Solutions

Modern JavaScript provides clean, native syntax operators to protect your code from these crashes.

1. Optional Chaining (?.)

The Optional Chaining operator (?.) allows you to read nested properties deep within a chain of connected objects without validating each reference manually.

If a property in the chain is null or undefined, the expression short-circuits and returns undefined instead of throwing a runtime error:

const avatarUrl = user?.profile?.avatar; 
console.log(avatarUrl); // Outputs undefined safely, no crash!

2. Nullish Coalescing (??)

Optional chaining prevents crashes, but returning undefined might break your UI layout (e.g., leaving image sources empty).

Combine optional chaining with the Nullish Coalescing operator (??) to provide a fallback default value. The ?? operator returns the right-hand operand only if the left-hand operand evaluates to null or undefined:

// Returns the default avatar if profile or avatar is missing
const avatarUrl = user?.profile?.avatar ?? '/images/default-avatar.png';

(Note: Avoid using logical OR || for fallbacks, as || treats empty strings "" or 0 as false, triggering the fallback value unnecessarily.)

3. Destructuring Default Values

When extracting values from objects, define default values directly in the destructuring assignment:

// Enforces default object parameters
const { profile = {} } = user || {};
const { avatar = '/default.png' } = profile;

4. Enable strictNullChecks in TypeScript

If you write TypeScript, configure your compiler to catch these bugs before the code runs. Open tsconfig.json and ensure strict checks are enabled:

{
  "compilerOptions": {
    "strict": true,
    "strictNullChecks": true
  }
}

With strict null checks enabled, the TypeScript compiler checks if a variable could possibly evaluate to null or undefined, and forces you to write optional checks or type guards before compiling.

Conclusion

The "Cannot read properties of undefined" runtime error is easily prevented using modern language utilities. By applying the optional chaining operator ?. to safely short-circuit deep property paths, combining it with the nullish coalescing operator ?? to provide safe default values, and enabling strict null checks in TypeScript, you can eliminate null reference crashes.