Search code examples
reactjsgraphqlgatsbycontentful

Accessing an array within an array using React, Gatsby and GraphQL


Using the Contentful CMS I've created a content model that allows for multiple items within a series of items. Part of the GraphQL query is as follows below:

   valueContainers {
    id
    title
    description
    singularValue {
      id
      subValueTitle
      subValueContent {
        subValueContent
      }
    }
  }

I'm able to display the titles of the top level sections (valueContainers) but I'm trying to map the singular value inner array within but I'm struggling to pass through the data. My code to map the array below is as follows:

    return (
    <ValuesWrapper>
        {props.valueList.map((value) => (
            <ValueContainer>
                <ValueTitle key={value.id}>{value.title}</ValueTitle>
                <ValuesDescription>{value.description}</ValuesDescription>
                {value.singularValue.map((item) => (
                    <SingleItem key={item.id}>{item.subValueTitle}</SingleItem>
                ))}
            </ValueContainer>
        ))}
    </ValuesWrapper>
)

I'm getting an error message on the front end that says:

Error in function eval

Cannot read properties of null (reading 'map')

Solution

  • Your approach looks good but my guess is that not all valueContainers has or contains singularValue (or in other words, is null in certain elements). Try:

    return (
    <ValuesWrapper>
        {props.valueList.map((value) => (
            <ValueContainer>
                <ValueTitle key={value.id}>{value.title}</ValueTitle>
                <ValuesDescription>{value.description}</ValuesDescription>
                {value.singularValue && value.singularValue.map((item) => (
                    <SingleItem key={item.id}>{item.subValueTitle}</SingleItem>
                ))}
            </ValueContainer>
        ))}
        </ValuesWrapper>
    )
    

    Or using a optional chaining operator:

    {value?.singularValue?.map((item) => (
        <SingleItem key={item.id}>{item.subValueTitle}</SingleItem>
    ))}
    

    how do I pass the value.singularValue as a prop to another component with this same method, do I just wrap the component in the same operators?

    If you wrap the component you are using it as a children but if you want to pass the value as props, simply use:

    {value?.singularValue?.map((item) => <SingleItem key={item.id} singleItem={item} />)}
    

    And the value will be under props.singleItem