About "TypeError: map is not a function" in JavaScript
Tags: javascript, webdev, beginners
Published: 2023-02-06 19:21:55

> ✋ **Update:** This post was originally published on my blog [decodingweb.dev](https://www.decodingweb.dev), where you can read the [latest version](https://www.decodingweb.dev/fix-map-is-not-a-function-error-in-javascript) for a 💯 user experience. _~reza_

The error “TypeError: object.map is not a function” occurs when you call the `map()` method on a non-array object in JavaScript. 

A non-array object can be an object literal, a string, a Map object, a Set object, etc.

Let’s see a simple example:

```js
let data = {
    course: 'JavaScript for Beginners', 
    language: 'JavaScript'
}

// This will cause the error
let newData = data.map(item => {
    // do something ...
    return item
})
```

The above code raises the "TypeError: object. map is not a function" error because the calling object isn't an array - it's an object literal.

## The `map()` method in JavaScript only works on arrays

The `map()` method is a part of the array prototype, meaning you can only call it on JavaScript arrays. Here's how MDN Web Docs defines it:

> **Array.prototype.map()**
> The `map()` method creates a new array populated with the results of calling a provided function on every element in the calling array.

```js
let data = ['apples', 'bananas', 'oranges', 'grapes']

// This is correct
let newArray = data.map(item => {
// do something here ...
return item
})
```

## How to solve "map is not a function" error in JavaScript

Whenever you encounter this error, inspect the variable calling `map()` - You can use `console.log(data)` to do so.

```js
console.log(data)
```

Before making any change to your code, ensure you're calling `map()` on the correct data object because you might be calling `map()` on an object, whereas you intended to refer to an array inside that object!

Here's an example:

```js
// ...

let data = {
    success: true,
    items: [
        {
            course: 'JavaScript for beginners'
        },
        {
            course: 'PHP programming'
        },
        {
            course: 'Learning Python'
        }
    ]
}

console.log(data.items)
```

If you called the `map()` method against the main data object, you'd have to change it to `data.items` instead:

```js
// ...

let newArray = data.items.map(item => {
    // do something here ...
    return item
})
```

Please note if data contains raw JSON, you should parse it into a valid JavaScript object literal with the help of `JSON.parse()`.

```js
// ...

data = JSON.parse(data)
```

## How to work around "... map is not a function" error when using object literals?

If you have an object literal and want to use it with the `map()` function, you need to convert your data into an array representation.

There are several ways to do this. Let's explore each with a quick example.

**Using Object.keys():** Since the `map()` function only works with array values, you can create an array from the keys in your object and call `map()` on the resulting array. 

Consequently, you can access the original object data using the key in a bracket notation: `data[key]`. 

Let's see how:

```js
// map-object-keys.js

let data = {
    course: 'JavaScript for beginners',
    language: 'JavaScript',
    creator: 'decodingweb.dev'
}

let dataKeys = Object.keys(data)
// dataKeys: ['course', 'language', 'creator']

let newData = dataKeys.map(key => {
    // Get the data from the original object with the bracket notation
    let item = data[key]
    
    // do something here ...
    return item
})
```

**Using Object.values():** Instead of object keys, you can create an array from the object values too:

```js
// map-object-values.js

let data = {
    course: 'JavaScript for beginners',
    language: 'JavaScript',
    creator: 'decodingweb.dev'
}

let dataKeys = Object.values(data)
// dataKeys: ['JavaScript for beginners, 'JavaScript'', 'decodingweb.dev']

let newData = dataKeys.map(itemValue => {
    // do something here ...
    return itemValue
})
```

**Using `Object.entries()` method:** If you need to access to key/value pair in your `map()` callback, you can use `Object.entries()`. This function creates an array consisting of `[key, value]` arrays:

```js
// map-object-entries.js

let data = {
    course: 'JavaScript for beginners',
    language: 'JavaScript',
    creator: 'decodingweb.dev'
}

let dataKeys = Object.entries(data)
/*
 dataKeys: [
    ['course',   'JavaScript for beginners']
    ['language', 'JavaScript']
    ['creator',  'decodingweb.dev']
]
*/

let newData = dataKeys.map(item => {
    // do something here ...
    
    console.log(item[0]) // key
    console.log(item[1]) // value
    
    return  item
})
```

**Add a length property to objects with integer-keyed properties:** If you have an object with numerical keys, you can make it map-ready by giving it a `length` property. After adding the `length` property, which should contain the number of properties in the object, you can call the `map()` method manually.

Let's see an example:

```js
// object-to-array.js

let data = {
    0: 'JavaScript',
    1: 'PHP',
    2: 'Python'
}

// Adding the length property
data['length'] = 3

/* 
The data now looks like this: 
{
    length: 3,
    0: 'JavaScript',
    1: 'PHP',
    2: 'Python'
}

*/

// We call the map directly from the Array prototype passing data as the context (this)
let newData = Array.prototype.map.call(data, item => item)
```

Since `map()` is a function, we can invoke it via `call()`. We pass our object as the context (`this`) to the call as the first argument. The second argument is the callback function, which is eventually passed to the `map()` method.

## If you're using JavaScript Map objects

If you're calling the `map()` method on a Map object, you'll still get this error.

Luckily, Map objects implement `keys()`, `values()`, and `entries()` methods. Using these methods, you generate arrays based on keys, values, or key/value pairs respectively (just like object literals in the above examples).

```js
//map-on-map-object.js

const map1 = new Map()

map1.set('a', 1)
map1.set('b', 2)
map1.set('c', 3)

// Since Map.prototype.keys() return a Map Iterator object, we use the spread operator to turn it into an array
let mapKeys = [...map1.keys()] // [1, 2, 3]

let newData = mapKeys.map(key => {
    // Do something here ...
    
    return [key, map1.get(key)]
})

// Create a new Map object with the transformed array
map2 = new Map(newData)
```

You could also use `map1.values()` and `map1.entries()` methods accordingly.

If you're working with a JavaScript Set object, the algorithm is the same.

## Adding a check: Array.isArray()

If you want to call the `map()` method only if the data is an array (without adjusting it), you can put your code inside a conditional statement:

```js
// map-array-if.js

let data = ['JavaScript', 'PHP', 'Python']
let newData = []

if (Array.isArray(data)) {
newData = data.map(item => {
         return item 
       })
}

console.log(newData)
```

As a result, the `map()` method will only be called if the respective data object is a JavaScript array.

## Wrapping up

Alright, I think that does it! Whenever you encounter this error, first check you're using an array. If the input isn't an array object, before anything, ensure you're referring to the right value. Then, depending on your object (object literal, Map, or Set) transform your data into an array, then call its `map()` method.

Additionally, you can check if the object is an array, and then, call the `map()` method against it.

Thanks for reading.

---

**❤️ You might like:**

- [TypeError: map is not a function in JavaScript in JavaScript (Fixed)](https://www.decodingweb.dev/fix-map-is-not-a-function-error-in-javascript)
- [SyntaxError: Unexpected end of JSON input in JavaScript (Fixed)](https://www.decodingweb.dev/syntaxerror-unexpected-end-of-json-input-in-javascript)
- [How to fix "ReferenceError: document is not defined" in JavaScript](https://www.decodingweb.dev/how-to-solve-referenceerror-document-is-not-defined)