React & REST API: How to render a list from a JSON response
Tags: react, javascript, node, tutorial
Published: 2021-05-21 16:15:46

---
published: true
title: React & REST API: How to render a list from a JSON response
description: Learn how to render a readable list from JSON data responded from a REST API request
series: React & REST API
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zmzgxjz5apt4r1kf74bf.png
tags: react, javascript, node, tutorial
---

In Part 4 of this series, we'll render the JSON data obtained in our last article in a cleaner way, instead of slapping the stringified REST API JSON response on to the browser.

![An screenshot of how JSON data looks when it's dirty and when it's clean](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hywmoi3xitbsi1kew0vi.png)

# <u>Add queries to the GET request</u>
First we'll fiddle around with the parameters we can use with [Kintone's Get Records API](https://developer.kintone.io/hc/en-us/articles/360019245194) request. Parameters help us specify how we want to retrieve the data - things like what query we want to use, and what fields we want in the response.

## Update the Field Codes
To help us specify parameters more easily in our code, we'll update our field codes. Field codes are unique identifiers of fields within the Kintone Apps. Notice how our JSON responses included some names like `Text_0` and `Text_1` - these are the field codes.

![A screenshot of the JSON response in the console with the field codes of Text_0 and Text_1 highlighted](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ctue7ntgxh8s7q9tycgy.png)

Field code names are automatically generated for fields when they are first dragged into the form of the Kintone App settings. The field codes can be update through the App's settings. Follow [the guide in the Help documents](https://get.kintone.help/k/en/user/app_settings/form/autocalc/fieldcode.html) to update the Field codes.

Through the App's settings, let's set:
- The "Title" field to have the field code `title`
- The "Author" field to have the field code `author`
- The "Record number" field to have the field code `recordID` (you'll need to drag and drop the Record Number field onto the form to update it's field code)

![A screenshot of the App's form editor with guides on which fields should be updated with what field codes](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f8m9t8braqbry671vvlz.png)

When done, click on "Save Form", and then "Update App" on the top right to apply the changes. If successful you'll notice that the API response in the console of the React App will be updated with the new field codes.

![2 screenshots of the JSON response in the console with one screenshot being before the field code change and the other screenshot being after the field code change](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v3asrwpy0afv9uqf8vil.png)

## Create the Query Parameters
Let's update our `server.js` code. Currently we're calling the Get Records end-point with one parameter, which is the **app** parameter. We'll want to add more parameters, but for readability's sake, let's remove the `?app=1` parameter from our current end-point declaration.

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

Within the `/getData` route, let's allocate the `?app=1` parameter to a constant, along with some other parameters.

```JavaScript
const parameters = "?app=1&query=order by recordID asc";
```

The **app** parameter is the same as before, pointing to the App ID of the Kintone App we want to get data from. The **query** parameter, `query=order by recordID asc` states to retrieve records from the Kintone App in ascending order of the Record Number value. You can check the [Kintone API documents](https://developer.kintone.io/hc/en-us/articles/360019245194#options) for more details on queries.

Let's attach `parameters` to the end of the API request endpoint in the fetch request.

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

The `/getData` route should now look like this.

```JavaScript
app.get('/getData', cors(corsOptions), async (req, res) => {
    const fetchOptions = {
        method: 'GET',
        headers:{
            'X-Cybozu-API-Token':process.env.API_TOKEN
        }
    }
    const parameters = "?app=1&query=order by recordID asc";
    const response = await fetch(requestEndpoint+parameters, fetchOptions);
    const jsonResponse = await response.json();
    res.json(jsonResponse);
});
```

Restart the Express server to apply the latest changes.

# <u>Clean the Response</u>
Now we'll move on to the client-side code. At the moment, the client-side's `index.js` is receiving the JSON response from `server.js`, and rendering the stringified version of it. This doesn't look very pretty 😑.

![A screenshot of the stringified JSON data on the React App](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5ctrcasu8te093gt6r1x.png)

Due to the updated parameters, the order of the data here has actually changed from the order listed in our previous article. This is hard to tell from our UI though, so let's render this data in a more user friendly way.

## Decide what will be rendered
Since we're collecting a list of records from our Kintone App, let's render the response as a list. Note that [Kintone's Get Records API](https://developer.kintone.io/hc/en-us/articles/360019245194) responds the list of records as an array of objects. We'll follow the [React document's example](https://reactjs.org/docs/lists-and-keys.html#rendering-multiple-components) on how to handle our array to be rendered as a list in our React App.

The first thing we'll do is update the `callRestApi` function. Let's remove the `stringify` statement, since in the code the response is easier to handle as JSON format.

```JavaScript
//return JSON.stringify(jsonResponse);
```

We'll then loop through Kintone's responded array using the [map function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map) to create an array of lists.


```javascript
const arrayOfLists = jsonResponse.records.map(
    record => <li><b>{record.title.value}</b> written by {record.author.value}</li>
    )
return arrayOfLists;
```
Note here that we are referencing our field values in our records by stating `record.title.value` (the value of the Title field) and `record.author.value` (the value of the author field).

The resulting array of lists will be returned to the `useEffect` hook, which will update the `apiResponse` state using `setApiResponse` (we don't need to make any changes to the code here). 

In the return statement of the `RenderResult` function, let's place `{apiResponse}` between `<ul>` elements, so we can render the array of lists.

```jsx
  return(
      <div>
          <h1>React App</h1>
          <ul>{apiResponse}</ul>
      </div>
  );
```

As a result, this will render our list of Kintone records as unordered lists.

![A screenshot of the React App with a clean list of manga titles and authors](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jd2etmzkq5hsd5b8f08n.png)

Hooray! We've done it!

Wait...have we checked the console...?🤭

![A screenshot of the React App with a clean list of manga titles and authors and an error in the console](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1ochuygw8ywgqiej9u51.png)

Aha...there seems to be a warning about "keys" 🗝️🤔

The react.js documents states [the following](https://reactjs.org/docs/lists-and-keys.html#keys) about keys:
> *Keys help React identify which items have changed, are added, or are removed. Keys should be given to the elements inside the array to give the elements a stable identity*

Basically, we need to assign a unique ID to each list we create. Instead of manually creating these keys though, we'll use the unique IDs stored in our Kintone App. The Record number field in Kintone is an auto-incremented field, unique to each record. In our map function, let's add the `key` attribute to our `li` element, and assign the value of the Record number field by stating `key={record.recordID.value}`.


```JavaScript
//return JSON.stringify(jsonResponse);
const arrayOfLists = jsonResponse.records.map(
    record => <li key={record.recordID.value}><b>{record.title.value}</b> written by {record.author.value}</li>
    )
return arrayOfLists;
```

Run our code again, and the issue should be solved!

![A screenshot of the React App with a clean list of manga titles and authors and no errors in the console](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4qj4lm74w34y3kct44px.png)

Great! Good job! ٩( 'ω' )و


# <u>The complete code</u>

The `server.js` code should end up looking like this.

```JavaScript
require('dotenv').config();
const express = require('express');
const cors = require('cors');
const fetch = require('node-fetch');

const PORT = 5000;
const app = express();

app.use(cors());
const corsOptions = {
    origin: "http://localhost:3000"
};

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

app.get('/getData', cors(corsOptions), async (req, res) => {
    const fetchOptions = {
        method: 'GET',
        headers:{
            'X-Cybozu-API-Token':process.env.API_TOKEN
        }
    }
    const parameters = "?app=1&query=order by recordID asc";
    const response = await fetch(requestEndpoint+parameters, fetchOptions);
    const jsonResponse = await response.json();
    res.json(jsonResponse);
});

app.listen(PORT, () => {
    console.log(`Example app listening at http://localhost:${PORT}`);
});
```

The `index.js` code should end up looking like this.

```JavaScript
import React, { useState, useEffect } from 'react';
import ReactDOM from 'react-dom';

const restEndpoint = "http://localhost:5000/getData";

const callRestApi = async () => {
    const response = await fetch(restEndpoint);
    const jsonResponse = await response.json();
    console.log(jsonResponse);
    //return JSON.stringify(jsonResponse);
    const arrayOfLists = jsonResponse.records.map(
      record => <li key={record.recordID.value}><b>{record.title.value}</b> written by {record.author.value}</li>
    )
    return arrayOfLists;
};

function RenderResult() {
  const [apiResponse, setApiResponse] = useState("*** now loading ***");

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

  return(
      <div>
          <h1>React App</h1>
          <ul>{apiResponse}</ul>
      </div>
  );
};

ReactDOM.render(
    <RenderResult/>,
    document.querySelector('#root')
);
```

Let me know in the comments if somethings not working well!

# <u>Next steps</u>
In the next part of the series, we'll add in some input fields and buttons onto our React App, which will add new records into our Kintone app.


　

                       ＿人人人人人人人人人＿
                       ＞ POST REQUESTS! ＜
                       ￣Y^Y^Y^Y^Y^Y^Y^Y￣
                       (\__/) 
                       (•ㅅ•) 
                       /つ つ