Building a Blog with React, Strapi & GraphQL - Create Post & Display it in Frontend
Tags: react, graphql, tutorial
Published: 2021-06-24 21:51:10

Hey there, this is the second part of the mini series in Building an app with React, Strapi, and GraphQL. In the first part that you can find [here](https://dev.to/semirteskeredzic/first-steps-in-building-app-with-react-strapi-apollo-graphql-1g64), we went through first steps in prepping the backend and frontend for our app.
In this part we will go through creating a blog post and displaying it in the list.

#Add Blog Post to the Strapi

First of all, spin up your Strapi environment with the command in the terminal from the directory that houses Strapi:
```
$ yarn develop
```
This will start the Strapi server so you can now navigate to `http://localhost:1337/admin/`, once you are there enter the login data for the admin user. 
Now in the left sidebar, chose `Content-Types Builder` and this will bring you to the list of your content type so click `Create Content Type`.
As a name enter `BlogPost` and press Continue, next you will be prompted to select a field for our content type:
![Strapi content type fields](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vkc6yhmtyawgv33tb2a7.png)


For a proper Blog post we need following fields:
- Title (Text - Short text)
- Body (Text - Long text)
- Tags (Text- Short text)
- CreatedAt (Date - datetime)

Go on and create those fields by selecting the type from the parentheses. Don't forget to click save after you have added them.

#Add a Blog post

In this case we will also use our Strapi backend. Make sure that the Strapi server is running and navigate to `http://localhost:1337`.
In the collection type section of the left sidebar under Collection Types click on BlogPosts. This will open a list of current BlogPosts with the button to add a new Blog post, press that button to add a new Blog post.
Fill out all the fields as you like and click Save and after that click Publish.
Now when you click on Collection Types BlogPosts you will see our new post in the list.
Next we will show the list of blog posts in the frontend of our application.

#Show the list of blog posts in frontend

If you followed steps from the first part in frontend folder we have everything ready to fetch the data from the Strapi backend.
In the `frontend` folder create a new directory under `src` named `queries` there create a new file named `blogPosts.js`.
In this file we will write a GraphQL query that will fetch us needed data from Strapi.

*frontend/src/queries/blogPosts.js*
```
import { gql } from '@apollo/client'

export const GET_BLOGPOSTS = gql`
  query {
  blogPosts {
    id
    Title
    Body
    Tags
    CreatedAt
  }
}`
```
*You can test queries by navigating to http://localhost:1337/graphql*

Now we need to write a component that will call this query and populate our table with the data, so let's create a `ListBlogPosts.js` inside `frontend/src/components`

*frontend/src/components/ListBlogPosts.js*
```
import React from 'react'
import { GET_BLOGPOSTS } from "../queries/blogPosts"
import {useQuery} from "@apollo/client";

function ListBlogPosts() {

    const {data, error, loading} = useQuery(GET_BLOGPOSTS)

    if(loading) return 'Loading...'
    if(error) return `Oops there has been an error: ${error}`
    if(data) return console.log(data)
}

export default ListBlogPosts
```
We will use this to test whether our query actually works!
If you save this, run the server with `yarn start` and navigate to `http://localhost:3000` you will see ..this:
```
Oops there has been an error: Error: Forbidden
```
And that is OK! It shows that our connection with Strapi works, that our basic error handler works because we are forbidden to read this data so this is Strapi issue.
Let's go back to Strapi backend and fix this, open Strapi backend and go to `Settings` and under `Users & Permissions Plugin` section select `Roles`. There you will see our `BLOG-POSTS` with all checkboxes deactivated, use `select all` to check all boxes and save it.
Now when you refresh `http://localhost:3000` you will see nothing but when you open console you will see we get the object. Success! Now let's show that in a way we humans understand it. Remove the line with `if(data)...` and create this return instead:

*frontend/src/components/ListBlogPosts.js*
```
...
if(error) return `Oops there has been an error: ${error}`

return(
        <div>
            <h1>List of Blog Posts</h1>
            <table>
                <thead>
                    <tr>
                        <th>ID</th>
                        <th>Title</th>
                        <th>Body</th>
                        <th>Tags</th>
                        <th>Created</th>
                    </tr>
                </thead>
                {data?.blogPosts && data?.blogPosts.length !== 0 ?
                    <tbody>
                    {data?.blogPosts.map(({id, Title, Body, Tags, CreatedAt}) => (
                        <tr key={id}>
                            <td>{id}</td>
                            <td>{Title}</td>
                            <td>{Body}</td>
                            <td>{Tags}</td>
                            <td>{CreatedAt}</td>
                        </tr>
                    ))}
                    </tbody> : <tbody><tr><td>No Blog Posts to show!</td></tr></tbody>}
            </table>
        </div>
)

export default ListBlogPosts
```
What did we do here? We created a simple table and we filled it with the data from Strapi. As you can notice we are using `data?.` with question mark, that is **optional chaining** because we don't want our code to throw exception if the data is somehow not ok. First we are checking whether blogPosts are there and whether we have blogPosts, we use `.length` here because we get an array of blogPosts so if there are blogPosts the `.length` won't be 0. If there are no blogPosts we show short info that there is no blog posts to show while if there are blogPosts we show them in the table through the map function. 

Now we see a simple table with all the data we entered in the Strapi backend. In the next steps we will add editing and removing options to this table so we can handle it directly from the frontend client.

Thank you for reading!