Why does array.map() return undefined when array exists in console.log?

11 replies
Last updated: Jul 1, 2021
how can I map over an array? I'm getting undefined when trying to use it. i can console log and see the array but when i try and map its returning undefined ?
AI Update

Based on your description, this sounds like a JavaScript/React issue where you're trying to .map() over data fetched from Sanity. The problem where you can console.log an array but get undefined when mapping usually happens due to one of these reasons:

1. Async timing issue - most common cause

If you're fetching data from Sanity, the data might not be loaded yet when your component first renders. Your .map() is running before the data arrives:

// ❌ Problem: data might be undefined initially
const MyComponent = () => {
  const [data, setData] = useState();
  
  useEffect(() => {
    fetchFromSanity().then(setData);
  }, []);
  
  return data.map(item => <div>{item.title}</div>); // undefined!
}

// ✅ Solution: Add a conditional check
return data?.map(item => <div>{item.title}</div>) || <div>Loading...</div>;

2. GROQ query returns an object, not an array

When you fetch a single document with GROQ, you get an object. If that object contains an array field, you need to access it:

// ❌ If your query is: *[_type == "page"][0]
// You get: { title: "My Page", items: [...] }
data.map() // undefined - data is an object!

// ✅ Solution: Access the array property
data.items?.map(item => ...)

3. The .map() itself returns undefined

Make sure your .map() callback actually returns something:

// ❌ No return statement
data.map(item => {
  <div>{item.title}</div>
})

// ✅ Implicit return with parentheses
data.map(item => (
  <div>{item.title}</div>
))

// ✅ Explicit return
data.map(item => {
  return <div>{item.title}</div>
})

Quick debugging checklist:

  1. Check what you're actually getting: console.log('type:', typeof data, 'value:', data)
  2. Add optional chaining: data?.map(...)
  3. Verify your GROQ query returns an array (use the Vision plugin in Studio to test queries)
  4. Make sure your map callback returns JSX

If you're using Next.js with server components, remember that you can fetch Sanity data directly without useState/useEffect, which eliminates the async timing issue entirely. Check out the next-sanity documentation for examples.

Show original thread
11 replies
Can I see some of your code? Are you asking about mapping over an array in JavaScript, or inside a GROQ query?
So I can console.log this array and i get the expected result, however when I map over it I get undefined ... is this a javascript async await issue?
Hm, that’s unexpected. Should not be async-related. What does
typeof submenu
say?
I assume it’s
submenu
you’re talking about
if i do an Array.isarray on the submenu it returns true ...
its so strange.
Does
.map()
actually work? What happens if you do:
submenu.map(console.log)
I think i found the issue, testing now
I wasnt fetching the staticpaths correctly i think
Thanks for your reply! In my static path query i was defining an object and not an array. wokring now.
Great!

Sanity – Build the way you think, not the way your CMS thinks

Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.

Was this answer helpful?