kampfkuchen
kampfkuchen

Reputation: 484

Access nested array in next.js

I am using nextjs and apollo for the first time and I am simply trying to use .map to iterate over database results.

Here is my component code:

import { gql, useQuery } from "@apollo/client"
import Link from "next/link"
import ErrorMessage from "../layout/ErrorMessage"

export const ALL_COURSES_QUERY = gql`
  query getCourses($limit: Int, $field: String!, $order: Order!) {
    courses(limit: $limit, sort: { field: $field, order: $order }) {
      courseFeed {
        id
        title
        videos {
          title
        }
        creator {
          id
          lastName
        }
        sections {
          title
        }
        ratings {
          id
        }
        deletedAt
      }
      pageInfoCourse {
        nextPageCursor
        hasNextPage
      }
    }
  }
`

export const allCoursesQueryVars = {
  limit: 10,
  field: "title",
  order: "ASC",
}

export default function CourseList() {
  const { loading, error, data } = useQuery(ALL_COURSES_QUERY, {
    variables: allCoursesQueryVars,
  })

  if (error) return <ErrorMessage message="Error loading courses." />

  const { courses } = data
  console.log(courses) // see output below

  return (
    <section>
      <ul>
        {courses.map((course) => (  // this does not work
          <li key={course.id}>
            <Link
              href={{
                pathname: "/courses/[slug]",
                query: { slug: course.slug },
              }}>
              <a>{course.title}</a>
            </Link>
            <p>{course.creator}</p>
          </li>
        ))}
      </ul>
    </section>
  )
}

console output

{
  __typename: 'CourseFeed',
  courseFeed: [
    {
      __typename: 'Course',
      id: '607c1f1201509f26b866cbba',
      title: 'Kurs Eins',
      videos: [Array],
      creator: [Object],
      sections: [Array],
      ratings: [Array],
      deletedAt: null
    }
  ],
  pageInfoCourse: {
    __typename: 'PageInfoCourse',
    nextPageCursor: null,
    hasNextPage: false
  }
}

Error Message

TypeError: courses.map is not a function

I would like to iterate over the courseFeed array to use the course objects in my page. I would be very thankful for any kind of help!!

Upvotes: 0

Views: 2498

Answers (1)

Ben Wainwright
Ben Wainwright

Reputation: 4651

In the data you have provided, you are trying to map over courses like it is an array, but it clearly isn't. courses is an object containing a property courseFeed which is an array. This should work:

<ul>
  {courses.courseFeed.map((course) => ( 
  {/* More stuff */}
</ul>

Edit

You've indicated in the comments that you are getting Error: Objects are not valid as a React child when you apply the above fix.

That error message is telling you exactly what the problem is. course.creator is neither a React element, string or undefined. It is an object (which we can see from the log message you posted in the question), which React can't use as a child element, which means the line

<p>{course.creator}</p>

is invalid.

Although the log message in your question doesn't give us any clue about the structure of that object, the error message in your comments rather helpfully does. object with keys {__typename, id, lastName}. I'm guessing you probably want to display the last name of the creator, so you'll need to amend that line to

<p>{course.creator.lastName}</p>

Upvotes: 4

Related Questions