Quick Answer
Value is not iterable (not an array, string, or iterable object). Check data types, ensure proper array initialization, and validate iterable objects before iteration.
Understanding the Issue
This error happens when attempting to iterate over values that do not implement the iterable protocol. JavaScript iteration works with arrays, strings, Maps, Sets, and other iterable objects, but not with regular objects, numbers, or null/undefined values.
The Problem
This code demonstrates the issue:
Javascript
Error
// Problem 1: Iterating over non-array
const userData = { name: "John", age: 30 };
for (const item of userData) { // TypeError: userData is not iterable
console.log(item);
}
// Problem 2: Spread operator on non-iterable
const config = { theme: "dark", lang: "en" };
const newConfig = [...config]; // TypeError: config is not iterable
// Problem 3: Destructuring non-iterable
const response = null;
const [first, second] = response; // TypeError: response is not iterable
The Solution
Here's the corrected code:
Javascript
Fixed
// Solution 1: Check if value is iterable before iteration
function isIterable(obj) {
if (obj == null) return false;
return typeof obj[Symbol.iterator] === "function";
}
function safeIterate(data) {
if (isIterable(data)) {
for (const item of data) {
console.log("Item:", item);
}
} else {
console.log("Data is not iterable:", typeof data);
}
}
safeIterate([1, 2, 3]); // Works - array is iterable
safeIterate("hello"); // Works - string is iterable
safeIterate({ name: "John" }); // Safe handling - object not iterable
// Solution 2: Convert objects to iterable when needed
const userData = { name: "John", age: 30, city: "New York" };
// Iterate over object keys
for (const key of Object.keys(userData)) {
console.log(`Key: ${key}, Value: ${userData[key]}`);
}
// Iterate over object values
for (const value of Object.values(userData)) {
console.log("Value:", value);
}
// Solution 3: Safe spread operator usage
function safeSpread(data) {
if (Array.isArray(data)) {
return [...data];
} else if (typeof data === "string") {
return [...data]; // Spread string into character array
} else if (isIterable(data)) {
return [...data];
} else {
console.log("Cannot spread non-iterable:", typeof data);
return [];
}
}
const array = [1, 2, 3];
const string = "hello";
const object = { a: 1, b: 2 };
console.log("Spread array:", safeSpread(array));
console.log("Spread string:", safeSpread(string));
console.log("Spread object:", safeSpread(object));
// Solution 4: Safe array destructuring
function safeDestruct(data) {
const safeArray = Array.isArray(data) ? data : [];
const [first = null, second = null] = safeArray;
return { first, second };
}
console.log("Destruct array:", safeDestruct([1, 2, 3]));
console.log("Destruct null:", safeDestruct(null));
console.log("Destruct object:", safeDestruct({ a: 1 }));
// Solution 5: API response validation
function processApiData(response) {
if (!Array.isArray(response)) {
console.error("Expected array, got:", typeof response);
return [];
}
return response.map(item => ({
name: item.name || "Unknown",
id: item.id || 0
}));
}
const validResponse = [{ name: "John", id: 1 }, { name: "Jane", id: 2 }];
const invalidResponse = { error: "Not found" };
console.log("Valid processing:", processApiData(validResponse));
console.log("Invalid processing:", processApiData(invalidResponse));
Key Takeaways
Check if values are iterable before using for...of loops or spread operator. Use Object.keys(), Object.values(), or Object.entries() for objects. Validate API responses are arrays before iteration.