skip to Main Content

I am getting a syntax error in my React return

Syntax error: Unexpected token, expected ","

If I remove

{data.nodes && data.nodes.map((node) => (
              {node.title}
              ))}

I get a different error BUT I do see all my JSON data in my terminal, so I know it is getting pulled. I am having trouble looping/mapping through it within my return

the error if I remove map…
Error: Objects are not valid as a React child (found: [object Promise]). If you meant to render a collection of children, use an array instead.

So my logic is to render the data as JSX and then pass it along from GetSlides to Page. You will see the {page} getting passed as well, but that works fine

async function GetSlides() {

const data = await getHomeSlides()
console.log(data)

 if (!data) return null;    
    
  return (
    
      <div>
        <h1>Slides</h1>

         {data.nodes && data.nodes.map((node) => (
          {node.title}
          ))}
      
     </div>
  )
    
}

export default function Page( {page} ) {


  return (
    <>
      <Layout>
        <Head>
          <title>{ page.seo.title }</title>
          <meta name="description" content={page.seo.metaDesc} />
        </Head>
       <Header />
        <ContainerFull>
          <h1>{ page.title }</h1>
            <GetSlides />
          <div dangerouslySetInnerHTML={{ __html: page.content }} />

          
        </ContainerFull>
      </Layout>
    </>
  )
}

This is the query

const API_URL = process.env.WORDPRESS_API_URL

async function fetchAPI(query, { variables } = {}) {
  const headers = { 'Content-Type': 'application/json' }

  if (process.env.WORDPRESS_AUTH_REFRESH_TOKEN) {
    headers[
      'Authorization'
    ] = `Bearer ${process.env.WORDPRESS_AUTH_REFRESH_TOKEN}`
  }

  const res = await fetch(API_URL, {
    method: 'POST',
    headers,
    body: JSON.stringify({
      query,
      variables,
    }),
  })

  const json = await res.json()
  if (json.errors) {
    console.error(json.errors)
    throw new Error('Failed to fetch API')
  }
  return json.data
}

export async function getHomeSlides() {
  const data = await fetchAPI(`
         {
          artwork {
            nodes {
              artwork {
                available
                description
                medium
                price
                size
                arttypedisplay
                homePageSlideshow
              }
              title
              uri
              slug
              seo {
                metaDesc
                title
              }
            }
          }
        }

  `)
  return data?.artwork
}

2

Answers


  1. Chosen as BEST ANSWER

    Thank you to Drew Reese for the great insight..

    the final code invloved putting both queries into getStaticProps

    import Head from 'next/head'
    import Link from 'next/link'
    import ContainerFull from '../components/container-full'
    import MoreStories from '../components/more-stories'
    import HeroPost from '../components/hero-post'
    import Intro from '../components/intro'
    import Layout from '../components/layout'
    import { getHomePage, getHomeSlides } from '../lib/api'
    import { CMS_NAME } from '../lib/constants'
    import Header from '../components/header'
    
    
    export default function Page( {page, artwork} ) {
    
        
    
      return (
        <>
          <Layout>
            <Head>
              <title>{ page.seo.title }</title>
              <meta name="description" content={page.seo.metaDesc} />
            </Head>
           <Header />
            <ContainerFull>
              <h1>{ page.title }</h1>
                
              <div dangerouslySetInnerHTML={{ __html: page.content }} />
    
            {artwork.nodes && artwork.nodes.map((arts) => (
              <span>{arts.title}</span>
              ))}
          
              
            </ContainerFull>
          </Layout>
        </>
      )
    }
    
    
    
    export async function getStaticProps({ params }) {
        
        
      const data = await getHomePage()
      console.log(data)
      
       const art = await getHomeSlides()
      console.log(art)
      
      return {
        props: {
          page: data,
          artwork: art,
        },
      }
    }
    

  2. You tried to make your GetSlides component async. React doesn’t work like that, the render function is 100% synchronous and should be free of side-effects. Do the data fetching in an useEffect hook and store result in local component state. An asynchronous function is declared inside the effect callback since react hooks are also synchronous.

    function GetSlides() {
      const [data, setData] = React.useState({
        nodes: [],
      });
    
      React.useEffect(() => {
        const fetchHomeSlides = async () => { // <-- create async function
          const data = await getHomeSlides()
          console.log(data);
          setData(data);
        };
    
        fetchHomeSlides(); // <-- invoke on component mount
      }, []); // <-- empty dependency array to run once on mount
    
      if (!data.nodes.length) return null; // <-- return null if nodes array empty
        
      return (
        <div>
          <h1>Slides</h1>
    
          {data.nodes.map((node, index) => (
            <React.Fragment key={index}> // <-- use react key
              {node.title} // <-- render title
            </React.Fragment>
          ))}
        </div>
      )
        
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search