0

I have a "Single Type" Page in Prismic with some normal content fields like uid or headline. It also has slice content with non-repeatable fields.

This is what my query looks like:

export const homeQuery = graphql`
  query Home {
    prismicHome {
      data {
        page_title {
          text
        }
        introline {
          text
        }
        hero_headline {
          text
        }
        body {
          ... on PrismicHomeBodyProjects {
            __typename
            primary {
              client_name {
                text
              }
            }
          }
        }
      }
    }
  }
`

And in my page I am returning it like this:

const IndexPage = ({ data: { prismicHome } }) => {

  return(
    <LayoutHome>
      <Hero
        introline={prismicHome.data.introline.text}
        headline={prismicHome.data.hero_headline.text}
      />
    </LayoutHome>
  )
}

But what I can't find out is how to map over my slice fields (i.e. client_name) without using the ApolloClient the are using in their docs?

My first naive attempt failed and returns a TypeError: Cannot read property 'data' of undefined:

const projects = homeQuery.prismicHome.data.body.primary.map(({ client_name }) =>
  <div>
    <h2>{client_name}</h2>
  </div>
)
Christoph Berger
  • 341
  • 1
  • 4
  • 16
  • What do you get if you conosle log `prismicHome ` in your page component? – ksav Aug 18 '19 at 08:43
  • 1
    Hey ksav! Sorry for the slow response, could figure it out as I misunderstood how those arrays are nested. Thanks anyway. – Christoph Berger Aug 22 '19 at 14:24
  • @ChristophBerger can you expand on your findings? I'm dealing with the same, I'm guessing you found something wrong with your path into the slice but I can't see anything wrong with it. – master Nov 12 '19 at 14:55
  • 1
    @master sure, I misunderstood how to map over data from slices, after mapping over the data you should use a switch statement to check for the various slices: ``` class ComponentName extends Component { render() { const slices = this.props.data.QUERYNAME.body.map(slice => { switch (slice.slice_type) { case "slice_name": return ( ) default: return null // or whatever you want to return in case it breaks } }) } return ( {slices} ) } ``` – Christoph Berger Nov 15 '19 at 21:55
  • 1
    @master, sry totally broke the code preview, will add it as another comment below, please feel free to reach out again if it does not work. – Christoph Berger Nov 15 '19 at 21:56

2 Answers2

0

try this:

//First add 'slice_type' to your slice query
...

... on PrismicHomeBodyProjects {
        slice_type
        __typename
        primary {
          client_name {
            text
          }
        }
      }
 ...


// Sort and display the different slice options

const PostSlices = ({ slices }) => {

  return slices.map((slice, index) => {

    const res = (() => {

      switch (slice.slice_type) {

        case "projects":
          return (
            <div className="slice" key={index}>
              {slice content...}
            </div>
          )
        default:
          return
      }
    })()

    return res
  })
}

  // Define the Post content returned from Prismic
  export default (props) => {

  const doc = props.data.prismicHome.edges.slice(0, 1).pop();
  const slices = doc.node.data.body;

  return (
    <div>
      <PostSlices slices={slices} />
    </div>
  )
}
Pawichi
  • 66
  • 5
  • Hey, figured it out a while ago and while answering @master s question above I saw your comment. Thank for that anyway. Quick question though, why are you recommending switching to the other plugin? – Christoph Berger Nov 15 '19 at 21:59
  • it has full support for Prismic Previews. It fetches data using Prismic's beta GraphQL API. It also provides an easy-to-configure interface for page generation. – Pawichi Nov 19 '19 at 13:30
  • [Update] I do not recommend the gatsby-source-prismic-graphl plugin anymore since it's not getting regular maintenance. So i'd say, stick with gatsby-source-prismic Thank you. – Pawichi Nov 13 '20 at 17:36
0

To provide an answer to @master s comment, I am putting my code bits here:

class ComponentName extends Component {

render() {
  const slices = this.props.data.QUERYNAME.body.map(slice => {
    switch (slice.slice_type) {
      case "slice_name":
        return (
          <Component
        prop={slice.primary.FIELDNAME.TYPE}
          />
        )
      default:
        return null // or whatever you want to return in case it breaks
    }
  })
}

return (
 {slices}
)

}
Christoph Berger
  • 341
  • 1
  • 4
  • 16