How to Resolve "TypeError: Cannot read properties of undefined (reading 'substring')" Error in JavaScript
The TypeError: Cannot read properties of undefined (reading 'substring') is a common JavaScript error that occurs when you try to call the .substring() method on a variable that does not hold a string value, but is instead undefined. This error is a clear indication that your code is trying to manipulate a variable that hasn't been properly initialized or assigned.
This guide will explain what the .substring() method is, the common reasons your variable might be undefined, and provide the standard, robust solutions to fix this error, from providing default values to using modern optional chaining.
Understanding the .substring() Method
The .substring() method is a function that exists only on strings. It is used to extract a portion of a string between two specified indices and returns a new string.
Correct Usage:
const message = "Hello, world!";
// This works because `message` is a string.
// Extracts the substring from index 7 to the end.
const sub = message.substring(7);
console.log(sub);
// Output: world!
Understanding the Error: Why undefined?
The error Cannot read properties of undefined (reading 'substring') happens when the variable you are calling .substring() on is not a string, but is instead undefined. The .substring() method simply does not exist on undefined.
Example of error:
let myString; // Declared but not initialized, so it is `undefined`
// The .substring() method does not exist on `undefined`.
// ⛔️ Uncaught TypeError: Cannot read properties of undefined (reading 'substring')
myString.substring(0, 5);
Common Causes of the Error
This error typically occurs for a few common reasons:
1. A variable was declared but never assigned a value
let username; // `username` is undefined
// ⛔️ Throws the error
const initials = username.substring(0, 2);
Solution: Always initialize variables to a sensible default, like an empty string ("").
2. An object property or array element does not exist
const user = { id: 1 }; // The 'name' property is missing
// `user.name` is undefined.
// ⛔️ Throws the error
const firstName = user.name.substring(0, 4);
3. A function that was expected to return a string returned undefined instead
function getGreeting() {
// This function doesn't return anything, so its result is `undefined`.
}
const greeting = getGreeting(); // `greeting` is now `undefined`
// ⛔️ Throws the error
const shortGreeting = greeting.substring(0, 5);
Solution 1: Provide a Fallback to an Empty String
If a variable might be undefined (e.g., from an API call), the easiest way to prevent the error is to provide an empty string ("") as a fallback using the logical OR (||) operator.
const dataFromApi = undefined;
// If `dataFromApi` is falsy (like undefined), use an empty string instead.
const message = dataFromApi || '';
// ✅ This is now safe. The .substring() method is called on an empty string.
const result = message.substring(0, 10);
console.log(result);
// Output: ""
This is a very common and effective pattern for ensuring a variable is always a string.
Solution 2: Use a Conditional Check Before Calling
A more explicit and often more readable solution is to check if the variable is actually a string before you try to call a string method on it. The typeof operator is the perfect tool for this.
const message = undefined;
if (typeof message === 'string') {
const result = message.substring(0, 10);
console.log(result);
} else {
console.log('Cannot get substring, because `message` is not a string.');
}
This approach makes your code very robust and its intent clear.
Solution 3: Use Optional Chaining (?.) for Safe Access
For modern JavaScript (ES2020 and newer), the optional chaining operator (?.) is the most concise and elegant solution. It allows you to safely attempt to call a method. If the value on the left is null or undefined, the expression "short-circuits" and returns undefined instead of throwing an error.
const message = undefined;
// The `?.` checks if `message` is null or undefined. Since it is,
// the .substring() call is never made. The expression returns `undefined`.
const result = message?.substring(0, 10);
console.log(result); // Output: undefined
You can combine this with the logical OR (||) operator to provide a default value.
const message = null;
// If the optional chain results in `undefined`, the `||` provides a fallback of "".
const result = message?.substring(0, 10) || '';
console.log(result); // Output: ""
Conclusion
The TypeError: Cannot read properties of undefined (reading 'substring') error is a clear signal that your variable is not the string you expected it to be.
To fix it, you must add a safeguard before calling the .substring() method:
- Initialize your variables (Best Practice): The most robust solution is to always initialize your string variables with a default value, like an empty string:
let message = "";. - Provide a Fallback: Use the logical OR operator for a quick and safe default:
const message = data || '';. - Use a Conditional Check: Use
if (typeof message === 'string')for clear and robust code. - Use Optional Chaining (Best for Conciseness): Use
const result = message?.substring(...) || '';for a clean, modern, and safe way to perform the operation on a potentiallyundefinedvalue.