Search code examples
reactjsgraphqlgatsbystrapi

Category of Post created by Strapi cannot be retrieved by GraphQL of Gatsby.js. However, it is displayed in GraphiQL of Gatsby.js


Category of Post created by Strapi cannot be retrieved by GraphQL of Gatsby.js. However, it is displayed in GraphiQL of Gatsby.js. 

I can call and display all but categories.

I am calling it as follows.

{categories.name}、{category.slug} I can't get these.

gatsby-config.js

     {
      resolve: `gatsby-source-strapi`,
      options: {
        apiURL:`http://localhost:1337`,
        collectionTypes: [`post`,`category`],
      },
    },

index.js

    const IndexPage = (props) => {
  const posts = props.data.allStrapiPost.nodes;
  return (
    <Layout>
      <Helmet>
        <title>title</title>
        <meta
          name="description"
          content="xxxxxxx"
        />
      </Helmet>
      <div className={styles.container}>
 
      <PostList posts={posts}  />
      
      </div>


    </Layout>
  );
};

export const query = graphql`
  query {
    allStrapiPost {
      nodes {
        title
        slug
        content
        thumbnail
        published_at (formatString: "YYYY.MM.DD hh:mm")
        categories {
          name
          slug
        }
      }
    }
  }
 
`;

export default IndexPage;

PostList.js

import React from "react"
import PostCell from "./PostCell";
import * as styles from "./PostList.module.css"

const PostList = props => {
  return (
    <>
      {props.posts.map(post => {
        return (
          <div className={styles.container}>
        <PostCell post={post} key={post.slug}  />
        </div>
        )

      })}
    </>
  )
}

export default PostList

PostCell.js

    import React from "react";
import { Link } from "gatsby";
import * as styles from "./PostCell.module.css";
import {Row,Col,Card,Button,container,OverlayTrigger} from 'react-bootstrap'


const PostCell = (props) => {
  const { title, content, categories, published_at, slug, thumbnail } = props.post;
  const plainContent = (content || "").replace(/(<([^>]+)>)/gi, "");
  return (


      <Card className={styles.container} >
            <Link to={`/posts/${slug}` } className={styles.link}>

          <Card.Img className="m-0" variant="top" src={thumbnail} alt={title} style={{width:`351px`,height:`160px`}}></Card.Img>
          <Card.Body  className={styles.cardContents} >
<Card.Title  variant="light" className={styles.cardTitle}>     {title}
</Card.Title>

<div className={styles.footer}>

<Link to={`/category/${categories.slug}`} >
<Button className="categoryButton" variant='primary' style={{padding:`5px`,fontSize:`10px`}}>{categories.name}</Button>
</Link>
<Card.Footer >{published_at}</Card.Footer>
</div>

        </Card.Body>
        </Link>

      </Card>
      

    

    

    
  );
};

export default PostCell;

enter image description here

The strapi role has been set. enter image description here


Solution

  • If you are able to see the categories in GraphiQL and not display them, your issue is in the view and how are you treating the data. In this case, (after the typical editions), categories is an array as posts are so unless you loop through them, you won't be able to display them.

    Do something like:

        import React from "react";
    import { Link } from "gatsby";
    import * as styles from "./PostCell.module.css";
    import {Row,Col,Card,Button,container,OverlayTrigger} from 'react-bootstrap'
    
    
    const PostCell = (props) => {
      const { title, content, categories, published_at, slug, thumbnail } = props.post;
      const plainContent = (content || "").replace(/(<([^>]+)>)/gi, "");
      return (
    
    
          <Card className={styles.container} >
                <Link to={`/posts/${slug}` } className={styles.link}>
    
              <Card.Img className="m-0" variant="top" src={thumbnail} alt={title} style={{width:`351px`,height:`160px`}}></Card.Img>
              <Card.Body  className={styles.cardContents} >
    <Card.Title  variant="light" className={styles.cardTitle}>     {title}
    </Card.Title>
    
    <div className={styles.footer}>
    
    <Link to={`/category/${categories.slug}`} >
    {categories.map(category=>{
       return <Button className="categoryButton" variant='primary' style={{padding:`5px`,fontSize:`10px`}}>{category.name}</Button>
    })}
    </Link>
    <Card.Footer >{published_at}</Card.Footer>
    </div>
    
            </Card.Body>
            </Link>
    
          </Card>
    

    The key part is:

    {categories.map(category=>{
       return <Button className="categoryButton" variant='primary' style={{padding:`5px`,fontSize:`10px`}}>{category.name}</Button>
    })}