React & REST API: How to add data to a Web Database
Tags: react, javascript, node, tutorial
Published: 2021-05-26 08:07:59

---
published: true
title: React & REST API: How to add data to a Web Database
description: Learn how to add a form to your React App that can add data to an external Web Database using REST API calls
series: React & REST API
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bitqsy7mxf5tdobweqcp.png
tags: react, javascript, node, tutorial
---

# <u>General Overview</u>
In Part 5 of this series, we'll add a form to our React App. Clicking a button will add a new record into our Kintone App, and the latest data will be re-rendered onto our React App.

![An image showing the React App before and after the re-render](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kzxsao390chtpta1j0n3.png)

# <u>System Overview</u>

Our React App will use the same Express server used in the previous articles as a proxy. The Express server will take in POST requests from our React App, make a request to our Kintone App (the web database), and add a new record into it.
After that, the React App will make a GET request to the Express server. The Express server will obtain records from our Kintone App, send back the result to the React App, and the result will be re-rendered on the UI.

![An image showing the system overview of this project where requests from the React App pass through the Express server to make API requests to Kintone](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1bz32lrbvje75ldpvo1w.png)

# <u>Update the Server Side Code</u>

We'll update the `server.js` code we've been working on in the series.

## 1. Set the Request End-points

We'll be making a REST API call to a [new end-point](https://developer.kintone.io/hc/en-us/articles/212494628) that will add a record into the Kintone App. Since we have 2 end-points now, for better readability let's first update our endpoint from this:

```JavaScript
const requestEndpoint = "https://{subdomain}.kintone.com/k/v1/records.json";
```

to this:

```JavaScript
const multipleRecordsEndpoint = "https://{subdomain}.kintone.com/k/v1/records.json";
const singleRecordEndpoint = "https://{subdomain}.kintone.com/k/v1/record.json";
```

The end-point called in the `/getData` route should also be updated from `requestEndpoint` to `multipleRecordsEndpoint`.

```JavaScript
//const response = await fetch(requestEndpoint+parameters, fetchOptions);
const response = await fetch(multipleRecordsEndpoint+parameters, fetchOptions);
```

## 2. Add a New Route

We currently have one route, the `/getData` route, that takes care of getting data from our Kintone App. Let's define another route that will take care of adding data into our Kintone App.

```JavaScript
app.post('/postData', cors(corsOptions), async (req, res) => {

});
```

The same CORS options used in our `/getData` route will be used in this `/postData` route. The settings inside this `/postData` route will be similar to the `/getData` route in terms of how the REST API is called, except that we'll have to set it to handle a POST request instead of a GET request.

The first thing we'll do in this `/postData` route is to define the request body needed for [Kintone's Add Record API](https://developer.kintone.io/hc/en-us/articles/212494628) call. The parameters **app** and **record** will be needed in this request.

```JavaScript
const requestbody = {
    "app":1,
    "record":{
        "title":{
            "value":req.body.title
        },
        "author":{
            "value":req.body.author
        }
    }
};
```

Make sure to set the App ID that you are using in your own Kintone domain for the **app** parameter. For the **record** parameter, we've set the key names as `title` and `author`. These are the [field code](https://get.kintone.help/k/en/user/app_settings/form/autocalc/fieldcode.html) names of the fields we want to populate data with when the record is added. The values for these keys are set as `req.body.title` and `req.body.author`, which are the values that will be included in the body of the POST request from the client side (initiated by a button click).

Next, let's declare the fetch options. As stated in [Kintone's API documentation](https://developer.kintone.io/hc/en-us/articles/212494628), we'll need to set the method as `POST` and the Content-Type as `application/json`. The body defined earlier will also be included in the options.


```JavaScript
const options = {
    method: 'POST',
    headers:{
        'X-Cybozu-API-Token':process.env.API_TOKEN,
        'Content-Type': 'application/json',
    },
    body: JSON.stringify(requestbody)
}
```

The option is then set in the 2nd argument of the fetch request.

```JavaScript
const response = await fetch(singleRecordEndpoint, options);
const jsonResponse = await response.json();
res.json(jsonResponse);
```

## 3. Set a Body Parsing Middleware

A body parsing middleware needs to be set on our Express server, so that the request body from the client side can be read successfully. ~~Let's install `body-parser` through the terminal.~~ --> *Sorry! Looks like body-parser was deprecated.*

~~We'll then declare the body parser at the top of our **server.js** code.~~

We'll use [express.json()](http://expressjs.com/en/api.html) to parse our incoming requests.

Set the following line after declaring `const app = express();`

```JavaScript
app.use(express.json());
```


And with that, our server side should be ready to read bodies of incoming requests. Let's restart the server to apply the changes (`ctrl+c` --> `node server.js`).


# <u>Update the API Token Settings</u>

The current API Token we use does not have permission to add new records into the Kintone App. Access the Kintone App's [API Token settings](https://get.kintone.help/k/en/user/app_settings/api_token.html) and update this API Token so that the "Add records" permission is included.

![A screenshot of the API Token settings of the Kintone App](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2u46qd9eexrf8d37f0t6.png)

Save the API Token settings, and click on the **Update App** button to have the new settings be applied to the production environment.

At this point, we can test to see if our Express server is working. By navigating to our React App, we can run the following code in the developer console to see if a successful request can be made to the server.

```JavaScript
const addRecordEndpoint = "http://localhost:5000/postData";
   
const options = {
        method: 'POST',
        headers:{
            'Content-Type': 'application/json'
        },
        body: JSON.stringify(
            {
            'title':'Test Title',
            'author':'Test Author'
            }
        )
    }

const response = await fetch(addRecordEndpoint, options);
const jsonResponse = await response.json();
console.log(jsonResponse);
```

If successful, the REST API call should return a JSON including the Record ID of the newly added record.

# <u>Update the Client Side Code</u>

Our next step is to update our client side code, **index.js**.
We need to:
- create a form with 2 input fields (one for the Title name, and one for the Author name) and 1 button
- send data to our Express server when a button is clicked
- re-render the list with the newest data

## 1. Set the Request End-points

We'll first need to declare the new end-point `/postData` defined earlier in our Express server. For better readability of our code, let's also update the constant name given to the `/getData` end-point.

```JavaScript
//const restEndpoint = "http://localhost:5000/getData";
const getRecordsEndpoint = "http://localhost:5000/getData";
const addRecordEndpoint = "http://localhost:5000/postData";
```

Don't forget to also update the end-point name called in the fetch call of the `callRestAPI` function from `restEndpoint` to `getRecordsEndpoint`.

```JavaScript
//const response = await fetch(restEndpoint);
const response = await fetch(getRecordsEndpoint);
```

## 2. Use States for the Input Fields

When we click the button in our form, we want to take the values inside our input fields, and send it in our REST API request. These input field values are best stored in states. In our example, we'll be placing two input fields in our form, one for the Title and one for the Author. Inside the `RenderResult` function, let's define the states that will manage our input values.

```JavaScript
const [titleValue, setTitleValue] = useState("");
const [authorValue, setAuthorValue] = useState("");
```

## 3. Create a Form

We'll create a form with two input fields and a button that will be used to send data to our Kintone App. This form will be defined in the return statement of the `RenderResult` function.

```jsx
return(
    <div>
        <h1>React App</h1>
            <ul>{apiResponse}</ul>
        <form>
            <div>
                <label htmlFor="title-input">Title:</label>
                <input type="text" value={titleValue} id="title-input" onChange={HandleTitleChange} />
            </div>
            <div>
                <label htmlFor="author-input">Author:</label>
                <input type="text" value={authorValue} id="author-input" onChange={HandleAuthorChange} />
            </div>
            <button type="button" onClick={ButtonClick}>Add data</button>

        </form>
    </div>
);
```

The `htmlFor` attribute is React's version of the `for` element, i.e. it associates the `label` with the `input` element. The initial input values are set as the data set in the `titleValue` and `authorValue` states. The 2 input fields and the button have events which will run functions when they are triggered. 

Our React App will currently display some errors in the console, since we haven't defined the `titleValue`,`authorValue` and `ButtonClick` functions yet. Let's quickly set these in the `RenderResult` function.

```JavaScript
function HandleTitleChange(){};
function HandleAuthorChange(){};
function ButtonClick(){};
```

Our React App should now render a form 😋

![A screenshot of the React App with a form under the list of records](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a8ls55md2dhqm82ksspe.png)

As an extra note, we're defining these functions within the `RenderResult` function, as those functions will be working with some state variables.

### 3a. Define the onChange functions

OK, so let's go ahead to update the functions called by the `onChange` event. These functions will set the current input field values in their relative states, `titleValue` and `authorValue`.

```JavaScript
function HandleTitleChange(event){
    setTitleValue(event.target.value);
}

function HandleAuthorChange(event){
    setAuthorValue(event.target.value);
}
```

### 3b. Define the Button Click function

When the button is clicked, we want our React App to:
- make a REST API call to the Express server
- re-render the UI to show that the data is being added
- re-render the UI with the latest data

So first, we'll update our `apiResponse` state to include a *now loading* message at the end of its list after the button is clicked. After that, we'll run an `AddNewRecord` function, passing in the values of the Title and Author input fields as its argument.

Let's update the `ButtonClick` function.

```JavaScript
function ButtonClick(){
    setApiResponse(apiResponse.concat(<li key="0" >*** now loading ***</li>));
    AddNewRecord(titleValue, authorValue);
}
```

Note that we needed to give the list a key, so we gave it an ID of 0, which is a number that is never assigned to a Record ID of a record in Kintone (more about keys were mentioned in the [previous article](https://dev.to/will_yama/react-rest-api-how-to-render-a-list-from-a-json-response-4964)). 

Now let's add the `AddNewRecord` function outside of the `RenderResult` function. The `AddNewRecord` function will be making our REST API call to the `/postData` end-point. 

```JavaScript
const AddNewRecord = async (Title, Author) => {

};
```

Inside this function, we'll first define the body parameters needed for [Kintone's Add Record API](https://developer.kintone.io/hc/en-us/articles/212494628). Although the documents state that the **app** parameter is also needed, we've already defined this parameter on the Express server side, so we won't need to include it on the client side. 

```JavaScript
const recordBodyParameters = {
    'title':Title,
    'author':Author
}
```

Next, we'll define the options needed for our fetch call to our Express server. 

```JavaScript
const options = {
    method: 'POST',
    headers: {
        'Content-Type':'application/json'
    },
    body: JSON.stringify(recordBodyParameters)
}
```

The options will then be set as the 2nd argument of our fetch call to the Express Server.

```JavaScript
const response = await fetch(addRecordEndpoint, options);
const jsonResponse = await response.json();
console.log(JSON.stringify(jsonResponse));
return jsonResponse;
```

So with this, we've defined a function that will send data (of the field values of the two input fields) to the Express server. 

The `AddNewRecord` function should look like this.

```JavaScript
const AddNewRecord = async (Title, Author) => {
  const recordBodyParameters = {
    'title': Title,
    'author': Author
  }

  const options = {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(recordBodyParameters)
  }

  const response = await fetch(addRecordEndpoint, options);
  const jsonResponse = await response.json();
  console.log(JSON.stringify(jsonResponse));
  return jsonResponse;
};
```

### 3c. Set the Render Timing

At this stage, we can test out our React App. Go ahead to place some data into the input fields and click the button.

![A gif of clicking the button to add a new record into Kintone although the list does not re-render with new data](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/slbpjyc71a994g3nq8v1.gif)

Although the *now loading* message is rendered and nothing happens after that, the data is successfully adde to our Kintone App.

![A screenshot of the Record list page of Kintone with the new data added](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/51d6tqptn7fbqm10gv2y.png)

Now that we've confirmed that a record can be added to our Kintone App, let's fix the rendering issue. After adding a new record, another REST API call needs to be made to Kintone to get the latest data, which will be used to re-render our React App.

To do this, we can utilize our existing `useEffect` hook that already makes a call to get the latest data from our Kintone App. The second argument of this hook is the `dependency array`, which determines the timing of when the hook should run. Currently this is set as `[]` which runs the hook only after the initial render. If we set a state instead for this dependency array, the hook will run when that state changes.

Within the `RenderResult` function, let's define a new state that will take care of when the `useEffect` hook will run. 

```JavaScript
const [successCounter, setSuccessCounter] = useState(0);
```

We'll call the `setSuccessCounter` function within the `ButtonClick` function. The `successCounter` state value will update after a successful REST API call from the `AddNewRecord` function.

```JavaScript
function ButtonClick(titleValue,authorValue){
    setApiResponse(apiResponse.concat(<li key="0" >*** now loading ***</li>));
    AddNewRecord(titleValue, authorValue)
    .then(response => 
        {
            setSuccessCounter(successCounter+1);
        }
    );
};
```

We need the `useEffect` hook to run whenever the `successCounter` state updates. We can do that by setting the `successCounter` state as the dependency array of the `useEffect` hook.

```JavaScript
useEffect(() => {
    callRestApi().then(
        result => setApiResponse(result));
},[successCounter]);
```

With this, the `useEffect` hook will run after a record is added into our Kintone App. The `useEffect` hook will get the latest records from the Kintone App and update the `apiResponse` state. The change in the `apiResponse` state will cause a re-render, so that all of the obtained records (including the newly added record) will be displayed on the React App.

![A gif of the React App with the button being clicked and the list of records being re-rendered with new data](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dxze1mbqk55lue7jjidc.gif)

Yay, we did it!

# <u>The complete code</u>

The complete code was pretty long, so I've summed up both `index.js` and `server.js` in [this GitHub repo](https://github.com/will-yama/react-and-rest-api/tree/main/Article%205:%20How%20to%20add%20data%20to%20a%20Web%20Database).


# <u>Next steps</u>

Why not post a new **dev.to** article with some updated version of this code? For example, the `onChange` events and related states can be merged, input fields can be cleared after clicking, and Memoizing can be used for better render performance. There are a whole lot of ways to make this code better 🤩

Let me know if you have any questions, issues or advices in the comments!


                       ＿人人人人人人人人人人＿
                       ＞ HAVE FUN CODING ＜
                       ￣Y^Y^Y^Y^Y^Y^Y^Y^Y￣
                       (\__/) 
                       (•ㅅ•) 
                       /つ つ