Search code examples
mappingcarouselgatsbysimplemodalcontentful

TypeError: undefined is not an object (evaluating 'nod.images.fluid') --


I am new in Gatsby and trying to place a image carousel on a modal. I have an array of images on Contentful and cannot map the images. I can do it outside of the modal but inside I can't reach to the array .

I tried to use different modals, different carousels but this is the best result that I can find.

These are the codes for carousel:

const CarouselUI = ({ position, handleClick, children }) => (
  <Container>
    {children}
    <Arrow onClick={handleClick} data-position={position - 1}>{'<'}</Arrow>
    <Arrow right onClick={handleClick} data-position={position + 1}>{'>'}</Arrow>
  </Container>
);
const Carousel = makeCarousel(CarouselUI)

These are the codes for component

const Product = ({ node }) => {
  const [showModal, setShow] = useState(false);

  const handleClose = () => setShow(false);
  const handleShow = () => setShow(true);

  return (
    <div>
      <figure>
        <Link href="/">
          <Image fluid={node.image.fluid} alt={node.title} />
        </Link>
        <figcaption onClick={handleShow}>
          <h4>Quick View</h4>
        </figcaption>
        <p>{node.title}</p>
        <p>{node.price}</p>
        <Modal className={product1Style.Modal} show={showModal} onHide={handleClose}>
          <section className={product1Style.modalheader}>
            <h1>{node.title}</h1>
          </section>
          <section className={product1Style.modalcontent}>
            <Modal.Body className={product1Style.row + ' ' + product1Style.center} closeButton>
              <div className={product1Style.col + ' ' + product1Style.colspan3}>
                <h4>{node.price}</h4>
                <div>
                  <button>Purchase</button>
                </div>
              </div>
              <div className={product1Style.col + ' ' + product1Style.colspan4}>
                <Carousel>
                  {node.images.map((nod) => {
                    return (
                      <Slide>
                        <Image fluid={nod.images.fluid} />
                      </Slide>
                    )
                  })}
                </Carousel>
              </div>
            </Modal.Body>
          </section>
        </Modal>
      </figure>
    </div>
  )
}

And this is my class:

class Product1 extends React.Component {

  render() {
      const ProductNecklace = this.props.data.productNecklace.edges

      return (
          <Layout>
              <section className={product1Style.lowerBody}>
                  <section className={product1Style.product1Necklace}>
                      <h3>Product1 Necklace</h3>
                      <div className={product1Style.productnecklaceimage}>
                          {ProductNecklace.map(({ node }, i) => (
                              <Product node={node} key={node.id} />
                          ))}
                      </div>
                  </section>
              </section>
          </Layout>
      )
  }
}


Solution

  • Your nod is the image itself, it's the iterable object from node.images, you can name it however you want. Without knowing the data structure, it's impossible to figure out how the map should be, but I guess that should look like:

    <Carousel>
      {node.images.map(image => {
        console.log(image)
        return (
          <Slide>
            <Image fluid={image.childImageSharp.fluid} />
          </Slide>
        )
      })}
    </Carousel>
    

    If you provide how's the GraphQL query, I will be able to infer how are the object and the arrays. Assuming that your node.images holds an array of images, inside each image you will need to access first to childImageSharp property before reaching fluid. As I said, your GraphQL query will be easier to debug. The console.log above the return statement will help you to know the nested properties.