2

I can console.log() the data I want after mapping through my data from my GraphQL query. However, the nested .map functions are not rendering my JSX. Is it possible to render JSX in nested .maps?

const NikonGallery = ({ data }) => {
return (
<Layout>
{data.allFiles.nodes.map((item) => {
        Object.entries(item).map(([key, value]) => {
          value.map((image) => {
            console.log("Individual image", image) // Logs show the data I want
            return ( 
              <>
                <GatsbyImage
                  image={image.gatsbyImageData}
                  alt={image.description}
                />
              </>
            )
          })
        })
      })}
 </Layout>
 )
}

export default NikonGallery

The data from GraphQL/Contentful is a nested array of objects. I'm having trouble getting the JSX to render when I call the nested objects via .map.

silencedogood
  • 3,209
  • 1
  • 11
  • 36
Alex Virdee
  • 121
  • 11

1 Answers1

1

Regarding the nested maps, you'll need to make some changes to return a proper expression from each map. The reason the console log works is because the code still loops; however, no expression is returned from the map for React to render. Try this:

data.allFiles.nodes.map((item) => {
    return Object.entries(item).map(([key, value]) => {
      return value.map((image) => {
        console.log("Individual image", image) // Logs show the data I want
        return ( 
          <>
            <GatsbyImage
              image={image.gatsbyImageData}
              alt={image.description}
            />
          </>
        )
      })
    })
  })}
</Layout>
)

When using the Gatsby image plugin for dynamic images such as this, you should use the getImage() method provided by the plugin. The import should look like this:

import { GatsbyImage, getImage } from "gatsby-plugin-image";

And the usage in your case would look something like this:

value.map((image) => {
        const gatsbyImage = getImage(image);
        return ( 
          <>
            <GatsbyImage
              image={gatsbyImage}
              alt={image.description}
            />
          </>
        )
      })
silencedogood
  • 3,209
  • 1
  • 11
  • 36
  • Trying that out didn't seem to output them. From the [docs](https://www.gatsbyjs.com/plugins/gatsby-plugin-image/) `getImage` *is an optional helper function to make it easier to read*. I could be wrong on that for this though. – Alex Virdee Nov 30 '21 at 00:42
  • @AlexVirdee please post your grapql query. If this didn't fix the issue, then your problem must reside in the query. Keep in mind you can't use GatsbyImage component on unparsed and untransformed images. – silencedogood Nov 30 '21 at 00:48
  • No problem I appreciate your help on this! Just edited the post to include the graphql query – Alex Virdee Nov 30 '21 at 00:56
  • @AlexVirdee you'll need to use childImageSharp in your query, along with sourcing the file system. Rather than me reinventing the wheel, I'll just [point you here](https://stackoverflow.com/questions/66907309/problem-using-gatsbyimage-of-gatsby-plugin-image-with-array) If this doesn't help let me know and I'll help get to the bottom of it. – silencedogood Nov 30 '21 at 00:59
  • Nice it is interesting `childImageSharp` isn't listed in the GraphiQl explorer. I am getting an error for now but lets just say there weren't any images. With the code I have now the image descriptions aren't showing up although I am able to console log them any thoughts on getting that to render? – Alex Virdee Nov 30 '21 at 01:04
  • @AlexVirdee In order to render with your current query you would have to use the StaticImage plugin, which will not work in a map function (static isn't meant for dynamic situations). You'll need a transformer such as childImageSharp. If childImageSharp isn't available it's usually because you're not sourcing the images correctly. – silencedogood Nov 30 '21 at 01:08
  • I understand the use cases for StaticImage and GatsbyImage. Just trying to output even maybe the 'dateAdded' for one of my assets. I don't think childImageSharp is needed for a string – Alex Virdee Nov 30 '21 at 01:21
  • @AlexVirdee oohh I see. I think that particular issue is simply because you're not declaring a return on the first two maps – silencedogood Nov 30 '21 at 01:23
  • Haha I was thinking this question is related more to mapping in jsx. If I try to return after a single map vs code will grey out the rest of the code for the other 2 maps so I don't think that's how to do it. – Alex Virdee Nov 30 '21 at 01:31
  • @AlexVirdee please let me know if my updated answer helps. If not I'll have to delete this answer and check on this later when I'm on a PC. – silencedogood Nov 30 '21 at 01:37
  • Appreciate your quick responses! The forEach method didn't work unfortunately – Alex Virdee Nov 30 '21 at 01:39
  • @AlexVirdee I took a final stab at this. It really should just be a matter of ensuring the expression is returned from .map... – silencedogood Nov 30 '21 at 01:48
  • 1
    Thank you so much for your help I was trying over the weekend with no luck. Marking this as correct! – Alex Virdee Nov 30 '21 at 02:04