How to Resolve "TypeError: .indexOf is not a function" Error in JavaScript
The TypeError: x.indexOf is not a function is a common error that occurs when you try to call the .indexOf() method on a value that is not an array or a string. This typically happens when you mistakenly assume a variable holds one of these types, but it actually holds a number, an object, null, or undefined.
This guide will explain the common causes of this error and show you the correct ways to solve it by either converting your data to the correct type or by using a defensive check before calling the method.
The Core Problem: .indexOf() is Only for Strings and Arrays
The .indexOf() method is a function that exists on the prototypes of two specific built-in types:
String.prototype.indexOf(): Searches for a substring within a string.Array.prototype.indexOf(): Searches for an element within an array.
It does not exist on any other data type. If you call it on a number, a boolean, a plain object, null, or undefined, JavaScript will throw a TypeError.
Cause 1 (Most Common): The Variable is a Number
This is a very frequent source of the error, especially with numeric IDs or codes.
Example of problem:
// Problem: `productId` is a number, not a string.
let productId = 12345;
// ⛔️ TypeError: productId.indexOf is not a function
let containsThree = productId.indexOf('3');
Solution: you must first convert the number to a string before you can call a string method on it. The String() constructor is the simplest way to do this.
let productId = 12345;
// ✅ Correct: First, convert the number to a string.
let productIdString = String(productId);
let indexOfThree = productIdString.indexOf('3');
console.log(indexOfThree); // Output: 2
Cause 2: The Variable is an Object or another Non-Iterable Type
You might have an object or another iterable (like a Set) and try to call .indexOf() on it directly.
Example of problem:
// Problem: `user` is an object.
let user = { name: 'Alice', id: 1 };
// ⛔️ TypeError: user.indexOf is not a function
user.indexOf('Alice');
Solution: your intent was likely to search one of the object's properties or to convert the object into an array first.
1. Search a Specific Property:
// ✅ Correct: Call `indexOf` on the string property.
let user = { name: 'Alice', id: 1 };
let hasL = user.name.indexOf('l');
console.log(hasL); // Output: 1
2. Convert an Iterable to an Array:
If you have an array-like object or another iterable (like a Set), you must first convert it to a true array with Array.from().
let mySet = new Set(['a', 'b', 'c']);
// ✅ Correct: Convert the Set to an array before using indexOf().
let myArray = Array.from(mySet);
let indexOfB = myArray.indexOf('b');
console.log(indexOfB); // Output: 1
Cause 3: The Variable is undefined or null
If a variable has not been initialized or a function did not return a value, it may be undefined.
Example of problem:
let myData; // `myData` is `undefined`
// ⛔️ TypeError: Cannot read properties of undefined (reading 'indexOf')
myData.indexOf('a');
Solution: guard your code to ensure you only call indexOf on a valid string or array. Optional chaining (?.) is a modern and concise way to do this.
let myData; // `myData` is `undefined`
// ✅ Safe: If `myData` is null or undefined, the expression returns `undefined`.
let result = myData?.indexOf('a');
console.log(result); // Output: undefined (no error thrown)
Practical Example: A Robust Search Function
This function demonstrates how to safely check for a value, handling different data types gracefully.
function safeIndexOf(data, searchValue) {
// Handle strings
if (typeof data === 'string') {
return data.indexOf(searchValue);
}
// Handle arrays
if (Array.isArray(data)) {
return data.indexOf(searchValue);
}
// Return -1 for all other types (objects, numbers, null, etc.)
return -1;
}
// Example Usage:
console.log(safeIndexOf('hello', 'e')); // Output: 1
console.log(safeIndexOf(['a', 'b'], 'b')); // Output: 1
console.log(safeIndexOf(123, '2')); // Output: -1
console.log(safeIndexOf(null, 'a')); // Output: -1
Conclusion
The TypeError: .indexOf is not a function is a clear signal that you are trying to use a method on the wrong data type.
- Remember that
.indexOf()is only available for strings and arrays. - If you have a number, you must convert it to a string first:
String(myNum).indexOf(...). - If you have an object, you must access one of its properties that is a string or an array:
myObj.myProp.indexOf(...). - If you have an array-like object or other iterable, convert it to an array first:
Array.from(myIterable).indexOf(...). - Use optional chaining (
?.) to prevent errors when a variable might benullorundefined.