sodcalculator

10 Tech How-To

Fix ‘map is not a function’ in JavaScript

Guide 10-30727 · Updated · Step by step

This error appears when you try to call .map() on something that isn’t an array. It’s common when you expect an array but get an object, a string, or undefined. This guide shows you how to diagnose and fix it quickly.

What You’ll Need

  • A browser’s developer console (F12) or Node.js
  • Access to the JavaScript code causing the error
  • Basic understanding of arrays and objects

Step-by-Step

  1. Reproduce the error – Open the console and trigger the code that fails. Note the exact error message and the line number.
  2. Check what you’re calling .map() on – Look at the variable before the .map(). If it’s not an array, that’s the problem. Use console.log(variable) to inspect it.
  3. Verify it’s an array – Use Array.isArray(variable) to confirm. If it returns false, you need to convert it or adjust the source.
  4. If it’s an array-like object – For example, a NodeList from document.querySelectorAll() or arguments. Convert it using Array.from(variable) or the spread operator: [...variable].
  5. If it’s a plain object – If you have an object like {name: 'John', age: 30}, you can’t map it directly. Use Object.keys(obj) to get an array of keys, or Object.values(obj) for values, then map over that.
  6. If it’s a string – Strings have no .map(). Convert to an array with str.split('') or Array.from(str) if you need to process characters.
  7. If it’s undefined or null – This often means the data hasn’t loaded yet. Add a guard: if (data && Array.isArray(data)) { ... } or use optional chaining: data?.map(...).
  8. Check for typos – Ensure you didn’t accidentally name a variable map or override Array.prototype.map.
  9. Test after each fix – Reload the page or re-run the code to see if the error is gone.

Common Mistakes

  • Assuming fetch responses are arrays – fetch() returns a Promise. You need to call .json() and then check if the result is an array.
  • Forgetting that querySelectorAll returns a NodeList – It looks like an array but isn’t. Always convert it.
  • Using map on a single object – If you get one object instead of an array of objects, wrap it in [obj] or handle it differently.
  • Ignoring asynchronous data – Data from an API might not be ready when you call .map(). Use async/await or .then() correctly.
  • Overwriting map – If you have a variable named map, it shadows the array method. Rename it.

Tips

  • Use console.log liberally to see what your variables actually contain.
  • Use Array.isArray() as a quick check before mapping.
  • Prefer Array.from() over spread for array-likes because it’s clearer.
  • For NodeList, you can also use Array.prototype.map.call(nodeList, fn) but it’s less readable.
  • In modern JavaScript, optional chaining (?.map) can prevent errors when the value is null/undefined.
  • If you’re using TypeScript, type your variables to catch this at compile time.

Troubleshooting

If the error persists, try these:

  • Check the exact line – The error message points to the line. Look at the variable there, not just the name.
  • Check for nested data – The array might be inside an object property, e.g., data.items.map(...) instead of data.map(...).
  • Use the debugger – Set a breakpoint at the line and inspect the variable in the debugger panel.
  • Search your code for reassignments – A variable might start as an array but get reassigned to something else later.
  • Check if the code runs in strict mode – In strict mode, this is undefined in functions, which can cause unexpected behavior if you’re using this.
  • If using a framework (React, Vue) – State might not be initialized as an array. Ensure the initial state is [].

Frequently Asked Questions

Why does .map() work on strings in some cases?

Strings don’t have a native .map() method. If you see it working, it’s likely because the string was converted to an array first, or you’re using a polyfill that adds it.

Can I use .map() on a Set or Map?

No, Set and Map don’t have .map(). Convert them to an array first: Array.from(set) or Array.from(map.values()).

What’s the difference between .map() and .forEach()?

.map() returns a new array with the results. .forEach() just iterates and returns undefined. Use .map() when you need a transformed array.

How do I handle .map() on data from an API?

Always check the response format. If the API returns an object with a results array, use data.results.map(...). If it returns an array directly, you’re fine.

Is there a performance issue with converting NodeList to an array?

No, the conversion is fast and negligible for most use cases. It’s worth the clarity and avoids errors.

Can I use .map() on a function’s arguments?

arguments is array-like but not an array. Convert it with Array.from(arguments) or use rest parameters (...args) instead.

Related

General steps for current mainstream versions; menus can differ by device and version. See the disclaimer or report an error.

More in this bed

The whole Tech How-To bed →