# '.map is not a function' — You're Not Holding an Array


*Adapted from the [JavaScript Essentials Companion Guide](https://systemcraftpress.com/guides/javascript-essentials/?utm_source=crosspost&utm_medium=syndication&utm_campaign=javascript-map-is-not-a-function).*

---

You fetch some data and try to loop over it:

```javascript
const response = { data: [1, 2, 3], total: 3 };

const doubled = response.map(x => x * 2);
```

```
TypeError: response.map is not a function
```

The message reads as if `map` is broken, or missing from your version of JavaScript. It isn't. `map` works fine. The error is describing `response`, and it's saying that this particular value doesn't have a `map` on it.

## What's actually happening

`map` isn't a general-purpose tool that works on any collection. It's a method that belongs to arrays specifically. When you write `something.map(...)`, JavaScript looks for a property called `map` on `something`. If `something` is a real array, it finds one and runs it. If it's anything else, it finds nothing, and calling nothing as a function produces "is not a function."

So the error never means "map failed". It means "the thing before the dot is not an array." The message even shows you which thing: `response.map is not a function` points at `response`. Your job is to find out what that value actually is and why it isn't the array you expected.

The usual suspects all look a bit like arrays, which is why this error confuses people:

- **An object that contains an array.** APIs often wrap their results, like `{ data: [...], total: 3 }`. The array is inside the object. The object itself has no `map`.
- **A Set or a Map.** They hold collections of values and can be looped over, but neither has `map`.
- **A string.** JSON you received but haven't parsed is just text, and text has no `map`.
- **An array-like object.** Things with numbered keys and a `length` look like arrays but aren't, and don't carry array methods. In browsers, `document.querySelectorAll()` returns a NodeList, which has `forEach` but not `map`.

## The fix, step by step

**1. Find out what the value really is.** Log it, along with its type, before the failing line:

```javascript
console.log(response, typeof response, Array.isArray(response));
```

`Array.isArray` is the reliable check. It returns `true` only for real arrays, and `false` for objects, strings, Sets, and array-likes.

**2. If it's an object holding the array, reach inside.** Use the property that contains the array:

```javascript
const doubled = response.data.map(x => x * 2);   // [2, 4, 6]
```

**3. If it's a Set, convert it to an array first.** Spreading it into an array literal does that:

```javascript
const set = new Set([1, 2, 2, 3]);
const doubled = [...set].map(x => x * 2);        // [2, 4, 6]
```

The same works for a Map (`[...map]` gives `[key, value]` pairs), and for a NodeList (`[...document.querySelectorAll('li')]`). For array-likes with numbered keys and a `length`, use `Array.from(arrayLike)`.

**4. If it's an object you want to loop over, use `Object.entries`.** It turns an object's key-value pairs into an array:

```javascript
Object.entries({ a: 1, b: 2 }).map(([key, value]) => key + value);  // ['a1', 'b2']
```

**5. If it's a string, parse it first.** A JSON string needs `JSON.parse` before it's an array:

```javascript
JSON.parse('[1, 2]').map(x => x);                 // [1, 2]
```

## Two mistakes worth knowing about ahead of time

**Silencing the error without finding the cause.** Wrapping the call in a check like `if (response.map) { ... }` makes the error go away, but the loop quietly never runs and you end up with a blank screen instead of a crash. Find out why the value isn't an array. If the data legitimately might be missing, handle that on purpose: `(items ?? []).map(...)` gives you an empty array to loop over when `items` is `undefined` or `null`.

**Confusing this with "cannot read properties of undefined".** If the value is `undefined` or `null`, you get a different message: `Cannot read properties of undefined (reading 'map')`. That one means the variable holds nothing at all, not a wrong kind of value. It has its own explanation in [How to Fix 'Cannot Read Properties of Undefined'](https://systemcraftpress.com/blog/cannot-read-properties-of-undefined/?utm_source=crosspost&utm_medium=syndication&utm_campaign=javascript-map-is-not-a-function).

## A habit that prevents the confusion entirely

When data comes from outside your code, from an API, a file, or user input, check its shape once at the edge, before it travels through the rest of your program. Log it, look at what's actually there, and write down in a comment or a type what you expect: "this is an object with a `data` array." Most `is not a function` errors come from assuming the shape instead of looking at it. A single `console.log` at the start usually settles the question in seconds.

---

*If you'd like more posts like this sent straight to your inbox, [subscribe to the newsletter](https://buttondown.com/SystemCraftPress?utm_source=crosspost&utm_medium=syndication&utm_campaign=javascript-map-is-not-a-function).*

*Prefer to dig in yourself? The [JavaScript Essentials repo](https://github.com/SystemCraftPress/javascript-essentials?utm_source=crosspost&utm_medium=syndication&utm_campaign=javascript-map-is-not-a-function) on GitHub has more free examples and exercises.*

