-2

I'm having trouble rendering a set of data that I'm fetching from an API, and would like to know why that is. If I comment out my map function, I'm able to console.log my data object and traverse it via the dev tools. However, once I implement the map function back into my code, I continually end up receiving a "cannot find property of reviews" TypeError. How is that? Considering I was able to console log the object earlier?

index.js

import Head from 'next/head'
import Image from 'next/image'
import styles from '../styles/Home.module.css'
import Header from '../components/Header'
import {useQuery, gql} from '@apollo/client'

const REVIEWS = gql`

  query GetReviews {
    reviews {
      title,
      body,
      rating, 
      id
    }
  }

`
export default function Home() {


  const {loading, error, data} = useQuery(REVIEWS)

  console.log(data.reviews)

  return (
    
    <>
    <Header/>

    <div>{data.reviews.map(r => (
      <div>{r.id}</div>
    ))} 
    </div>

    </>
  )
}

_app.js

import '../styles/globals.css'
import {
  ApolloClient,
  InMemoryCache,
  ApolloProvider,
} from "@apollo/client";




function MyApp({ Component, pageProps }) {


 const client = new ApolloClient({
   uri: 'http://localhost:1337/graphql',
   cache: new InMemoryCache()

 })


  return (

        <ApolloProvider client={client}>
          <Component {...pageProps} />
        </ApolloProvider>
  
  )
}
export default MyApp
gummyguppy
  • 53
  • 5
  • Perhaps it is throwing an error while the query is loading if `data` or `data.reviews` is undefined. Depending on your build system you may be able to do optional chaining and dodge the error if either of those are undefined: `data?.reviews?.map(...` – Marc Baumbach Jul 29 '21 at 00:50
  • just follow docs ... `if(loading) return ` protects from this kind of errors ... explained hundreds times, use search!! – xadm Jul 29 '21 at 07:34

1 Answers1

1

Please make sure that you always use a condition to check if the data is there, before starting to map over it in the event of fetching data.

In your example, a simple solution would be:

return (
  <>
    <Header />

    <div>
      {data?.reviews.length ? data.reviews.map((r) => <div>{r.id}</div>) : null}
    </div>
  </>
);

What I did was check if data.reviews is not undefined and if it has a positive length ( > 0 ), which is a requirement in order to be able to map over it. If this requirement is not fulfilled, null is returned instead.

Kevin Haxhi
  • 498
  • 2
  • 6