Introduction to JSON Server (part II)
Published: 2022-09-03 19:16:02

`As a frontend developer, when prototyping you need to know how to fetch data from your JSON Server, in this last part we are going to learn just that.Check out` [the first part](https://dev.to/derick1530/introduction-to-json-server-beginner-part-i-4l2g)

**Prerequisite**

- 
To follow this article along, prior knowledge of React Hook,React Suspense API and JSON Server is essential.
- 
Here is the [GitHub repo](https://github.com/Derick1530/introduction-to-json-server.git) (instructions are in the readme file)

## Introduction

In this part, we are going to put into practice some request types (POST, GET, PUT, PATCH, and DELETE).
Before we start, in part 1 we were able to fetch data inside our database.json by playing with the URL, It will be the same but instead of making changes to the URL, we will write some codes.


> Side note: we are using react Suspense API for data fetching. You can read more about it [here](https://dev.to/derick1530/reactsuspense-for-data-fetching-part-1-4a0h) as it is not under the scope of this article.

## GET request
The application is running on `localhost:3000`
and the server on port `localhost:7000`;

**GET ALL ITEMS**
In your project repo navigate to fetchFici.js under web-client/src/page/

We are going to create a fetch function to get our data from JSON server.
in the first line above wrapPromise type enter this code:
```javascript
const readAllFici = () => {
    return fetch("http://localhost:7000/data")
        .then(res => res.json())
        .catch(err => console.log(err))
}
```
In createRousource file add readAllFici() in wrapPromise like this:

```javascript
export const createResource = () => {
    return {
        data: wrapPromise(ReadAllFici())
    }
}
```

In the first snippet we created a function and named it 
readAllFici, we passed the json server url in the first parameter, we then got back a response from the server.

Next snippet we are passing fetch function to createResource which is part of the structure of using [react Suspense](https://dev.to/derick1530/reactsuspense-for-data-fetching-part-1-4a0h).

Next, still in the same folder navigate to index.jsx 
we will import createResource and it in our Screen component like this:

```javascript
import { createResource } from './fetchFici';

const resource = createResource();
return (
   <Suspense fallback={<Spinner />}>
      <Screen resource={ressource} />
   </Suspense>
);
```
In screen.jsx add this snippet:
```javascript
const Screen = ({ resource }) => {
    const ficiData = resource.data.read()

    const displayFici = ficiData.map((item, index) => {
        return (
             ...
       )
...
```
The above snippet we are getting the data sent by the server.
to see the result in your browser, refresh the page.

![fetched data](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/why6foc1ujjxej9qoabv.png)
We received all the items from the server and passed them inside the component.

**GET A SINGLE ITEM**
To get a single element we are going to change the fetch url to "/{the id of our item}"
Let's implement that.

First, create a new function to fetch item based on the id:

```javascript
const readOneItem = (id) => {
    return fetch(`http://localhost:7000/data/${id}`)
        .then(res => res.json())
        .catch(err => console.log(err))
}
```
Next, bellow createResource we create a new arrow function, the same as createResource but with a parameter, and that parameter will be received by readOneItem.
```javascript
export const createResourceOnePost = (id) => {
    return {
        data: wrapPromise(readOneItem(id))
    }
}
```
Next in singlePost.jsx we have two components one that receives the data and passes it through the component and one that displays it. Before that, we need to get the id of a single element. For our case, we used react-router-dom (you can check in App.jsx how we set up the routing).
In the second component we are going to get the id param from the URL, for that let's import useParams() and get the id:

```javascript
import { useParams } from 'react-router-dom'

const { id } = useParams()
```
Let's import createResourceOnePost and call the first component inside Suspense which takes `ressource` as parameter.

```javascript
import { createResourceOnePost } from './fetchFici'
const resource = createResourceOnePost(id)
 return (
        <div className='border rounded-md bg-zinc-800 border-white p-4'>
            <p className='text-center text-3xl font-mono'>Fici Game</p>
            <Suspense fallback={<Spinner />}>
                <LoadData resource={resource} />
            </Suspense>
        </div>
    )
```
Inside the child component let use the data passed in the parent component.
```javascript
const LoadData = ({ resource }) => {
    const ficiData = resource.data.read()

    return (
        <div className='border bg-gray-900 flex flex-col space-y-4 justify-center items-center border-white h-80 m-4'>
            <p className="p-4 font-mono text-lg">{ficiData.name}</p>
            <span className='text-9xl shadow-2xl rounded-full'>{ficiData.symbol}</span>
        </div>
    )
    }
```
The last thing we need to do is to navigate to the specific item.
In screen.jsx create a onClick inside displayFici

```javascript
import { useNavigate } from 'react-router-dom';

const navigate = useNavigate()
const displayFici = ficiData.map((item, index) => {
        return (

            <tr className='border-b border-gray-500 cursor-pointer' onClick={() => {
                navigate(`/${item.id}`)
            }} key={index}>
                <td className='p-2'>{item.id}</td>
                <td className='p-2 text-center'>{item.name}</td>
                <td className='p-2'>
                    <span className='text-xl'>{item.symbol}</span>
                </td>
            </tr>

        )
    })
```
**Output**

![Fetch Single Item](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/glg4e0k36jqgrbcst5tf.png)

## POST METHOD
Let's add a third element to our list of items.
to do that we need to create a function, the same way we did for get request but instead of getting it, we will post (send) data to our JSON server.
so let's create that in fetchFici.js
```javascript
export const postItem = () => {
    const doc = {
        name: 'Tornado',
        symbol: '🌪️'
    }
    return fetch('http://localhost:7000/data', {
        method: "POST",
        body: JSON.stringify(doc),
        headers: { 'content-Type': 'application/json' }
    })
}
```
We created a doc object where we passed manually the item we want to add to our list, then to add that item inside our database.json we need to fetch, the first parameter is the URL this time it will receive a second parameter which is an object inside we pass the method which is POST for our case, the body, and the headers.

we do the same as we did for get request.
We import the function in screen.jsx component and it will be executed once a button is clicked.
```javascript
import { postItem } from './fetchFici';

<div>
     <p className='text-center p-2'>➕</p>
     <div className='text-center'>
        <button className='bg-sky-700 rounded-lg w-20 p-2' onClick={() => { postItem() }}>🌪️</button>
        <p className='font-mono'>Tornado</p>

     </div>
</div>
```
Now if you click to the button and refresh the page, you will see an item have been added(read more about useEffecf [here](https://dmitripavlutin.com/react-useeffect-explanation/)

![add new item](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tqhfv0woz7z7jt689ycl.png)
if you check in our database.json instead of having 4 we now have 5 items. So far so good, now you know how to get and post data from the JSON server, next let's see how to Update and delete data.

## UPDATE AND DELETE DATA
Update is almost the same thing as other types of requests, we are just changing the method to PUT or PATCH instead of POST.
side note: The difference between PUT and PATCH is that when you use PUT you have to specify all the properties inside your object body, if you need to update only one property you can make use of PATCH request.

So go ahead and create a new function and call it updatItem in fetchFici.js

```javascript
export const updateItem = (id, body) => {
    return fetch(`http://localhost:7000/data/${id}`, {
        method: "PATCH",
        body: JSON.stringify(body),
        headers: { 'content-Type': 'application/json' }

    })
}
```
In the code above we passed two parameters: the id for the item we want to update and the new name.

Now in singlePost.jsx let's add some lines of code.

```javascript
import { updateItem } from './fetchFici'
import React, { useState } from 'react'


const LoadData = ({ resource }) => {
    const { id } = useParams();
   const [text, setText] = useState('');
    return (
   ...
            <span></span>
            <form onSubmit={updateHandler} className="flex flex-col">
                <input className='text-gray-700 text-center rounded-lg p-1' type="text" placeholder={ficiData?.name} value={text} onChange={(e) =>
                    setText(e.target.value)
                } />
                <button type='submit' className='p-4 bg-zinc-800 rounded-b-lg'>UPDATE</button>
            </form>
    )
}
```
Output

![ui update](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ouau265qng7s3zcottna.png)
Now if you change the name and click update, then refresh the page you should see the changes; in my case i updated Air to Vortex

![name updated ](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5prnjjh79czvuw3wmp6u.png)

**DELETE ITEM**

Now let's see how to delete an item.
You already know how to create a query function,
go ahead and create a function similar to updateItem
then remove all the object body as it is not needed, then change the request method to DELETE, don't forget to pass the id parameter, you need to know which item you want to delete from the list of items

```javascript
import { deleteItem } from './fetchFici';

export const deleteItem = (id) => {
    return fetch(`http://localhost:7000/data/${id}`, {
        method: "DELETE"
    })
}
```

Next let's add some code in screen.jsx

```javascript
  <td>
      <button className='p-1' onClick={() => {
                        deleteItem(item.id)
                    }}><TbTrash className='text-red-600'/>
     </button>
</td>
```
We imported deleteItem, inside displayFici we added a new `td` tag with a button, passed the deleteItem in `onClick`.

Output

![Delete button](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sts30834kcllqt5qy3nh.png)

Click to one item then refresh the page you will see the item has been deleted.

![item deleted](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j5xmy21ryxycmyp795vq.png)

## Conclusion
We have reached the end of our tutorial, We saw some types of requests that are useful for testing endpoints when prototyping.
For those types seen in the first part, I highly recommend you to go and try to implement them, and let me know in the comment if you encounter any challenges implementing them, I will be glad to help.
If you find this article helpful, don't forget to share it with your friends.

full source code [GitHub repo](https://github.com/Derick1530/introduction-to-json-server/tree/final)
Learn more about React Suspense API[ here](https://dev.to/derick1530/reactsuspense-for-data-fetching-part-1-4a0h)

Until next time, take care.