React.js

ReactJS API Calls Example

In this article, we will take a look at making API Calls in a ReactJS application. Making API Calls to perform CRUD operations on data is a critical and important feature of most applications. We gain an understanding and learn the intricacies of achieving the same in with ReactJS. ReactJS has soared in popularity and has become the go-to library for Front end Development.

So without further ado let us get started and build an example ReactJS application.

I have used the following toolset and technologies to build the example in this article.

1. Tools and Technologies

create-react-app npm package from the folks at Facebook allows us to quickly generate a ReactJS application. We use it here to scaffold a starting point for our example. The latest ReactJS version is pulled down and used by create-react-app. ReactJS is a front end library and we use it here to show how to make API calls in a ReactJS application.

I have used Express to create a rudimentary API for the purposes of our example in Nodejs. concurrently allows us to run multiple commands concurrently like our server API and client-side code here. Visual Studio Code IDE is my editor of choice for front end development although you are free to follow along in an editor of your choice.

2. Project Structure

To generate our project we run the below command:

>npx create-react-app my-app

The npx command downloads a temporary copy of a package and runs it with the parameters provided. And once the above command completes running we should have the following project structure ready.

ReactJS API Calls - Project Structure
Project Structure

3. Server-side API

We will create a rudimentary API for use in our example. The API is backed by a sample dataset on which we will perform CRUD operations. The dataset represents a Cricket team of my favorite players. We will edit this list including add/remove players and update player names calling the server-side API each time. The changes will not be persistent as we will not use a backing database store for the sake of keeping things simple. Our dataset looks like below:

dataset.json

[
    {
        "name": "Sachin Tendulkar"
    },
    {
        "name": "Gautam Gambhir"
    },
    {
        "name": "Sourav Ganguly"
    },
    {
        "name": "Anil Kumble"
    },
    {
        "name": "Virendar Sehwag"
    },
    {
        "name": "Jasprit Bumrah"
    },
    {
        "name": "Viraat Kohli"
    },
    {
        "name": "Ravindra Jadeja"
    },
    {
        "name": "Javagal Shreenath"
    },
    {
        "name": "Kuldeep Yadav"
    },
    {
        "name": "Rahul Dravid"
    },
    {
        "name": "Venkatesh Prasad"
    }
]

To realize the Server-side API I have used Express and the code for the Server-side looks like below:

index.js

const express = require('express');
const app = express();
const bodyParser = require("body-parser");
const api = require('./teamController');
const cors = require('cors');

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(cors());
app.use('/api', api());

const Port = process.env.PORT || 2019;

app.listen(Port, () => {
    console.log(`Listening on ${Port}.`);
});

The code for the team controller which handles the API request looks like below:

teamController.js

const router = require('express').Router();
let dataset = require('../dataset/dataset.js');
module.exports = () => {
    router.get('/', (req, res) => {
        return res.json(dataset);
    });

    router.post('/addPlayer', (req, res) => {
        dataset.push(req.body);
        return res.json({ success: "success" });
    });

    router.patch('/updatePlayer/:oldName/:newName', (req, res) => {
        let player = dataset.map(p => p.name.toLowerCase() ===
 req.params.oldName.toLowerCase());
        player.name = req.params.newName;
        return res.json({ success: "success" });
    });

    router.delete('/deletePlayer/:name', (req, res) => {
        dataset = dataset.filter(p => p.name.toLowerCase() !==
 req.params.name.toLowerCase());
        return res.json({ success: "success" });
    });

    return router;
};

Now let’s move on to our client-side application and to making the actual calls to this API.

4. Client-side API Calls

Going about client-side development, I have created three ReactJS components namely, TeamPage, PlayerList, and Player. The TeamPage component hosts our UI. Whereas the PlayerList renders an unordered list of Players from our team. Each player is further passed onto an instance of the Player component to be displayed. Furthermore, the API calls are made from the TeamPage Component with the other two components acting as dumb or not so smart ones.

To make the actual API calls we use the fetch browser API. The code for each of the components discussed above looks like below.

TeamPage.js

import React, { useState, useEffect } from 'react';
import PlayerList from './PlayerList';
import dataService from '../Services/DataService';

function TeamPage(props) {
    const [team, setTeam] = useState();
    useEffect(() => {
        dataService.getTeam()
            .then(resp => setTeam(resp))
            .catch(err => console.log(err));
    }, []);
    const deletePlayer = (name) => {
        dataService.deletePlayer(name)
            .then(r => {
                dataService.getTeam()
                    .then(resp => setTeam(resp))
                    .catch(err => console.log(err));
            })
            .catch(err => console.log(err));
    }
    const updatePlayer = (oldname, newname) => {
        dataService.updatePlayer(oldname, newname)
            .then(r => {
                dataService.getTeam()
                    .then(resp => setTeam(resp))
                    .catch(err => console.log(err));
            })
            .catch(err => console.log(err));
    }
    return <div style={{
        display: 'flex',
        flexDirection: 'column',
        height: '100vh',
        width: '100vw',
        justifyContent: 'center',
        alignItems: 'center'
    }}>

        <PlayerList team={team} updatePlayer={updatePlayer}
deletePlayer={deletePlayer} addPlayer={addPlayer} />
    </div>
}

export default TeamPage;

PlayerList.js

import React, { useState } from 'react';
import Player from './Player';

function PlayerList(props) {
    const [newPlayer, setNewPlayer] = useState("");
    const handleChange = ({ target }) => {
        setNewPlayer(target.value);
    }
    const handleClick = () => {
        if (!newPlayer) return;
        props.addPlayer(newPlayer);
    }
    return <>
        <input type="text" value={newPlayer}
 onChange={handleChange} /><button 
onClick={handleClick}>+</button>
        <ul>
            {props.team && props.team.map(p => <Player
                updatePlayer={props.updatePlayer}
                deletePlayer={props.deletePlayer}
                key={p.name} player={p} />)}
        </ul></>
}

export default PlayerList;

Player.js

import React, { useState } from 'react';

function Player(props) {
    const [editMode, setEditMode] = useState(false);
    const [playerName, setPlayerName] = 
                                     useState(props.player.name);
    const handleChange = ({ target }) => {
        setPlayerName(target.value);
    }
    const saveChanges = ({ target }) => {
        props.updatePlayer(props.player.name, playerName);
        setEditMode(false);
    }
    const deletePlayer = () => {
        props.deletePlayer(playerName);
    }
    return <>
        {!editMode && <li>{playerName}</li>}
        {editMode && <><input value={playerName} onChange=
{handleChange} /><br /></>}
        {!editMode && <><button onClick={() => 
{ setEditMode(true) }}>Edit</button><button onClick=
{deletePlayer}>X</button></>}
        {editMode && <button onClick={saveChanges}>Save</button>}
    </>;
}

export default Player;

The code for the dataService looks like below:

DataService.js

function getTeam() {
    return window.fetch('/api')
        .then(r => r.json());
}

function addPlayer(player) {
    return window.fetch('/api/addPlayer', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json'
        },
        body: JSON.stringify(player)
    })
        .then(r => r.json());
}

function updatePlayer(oldname, newname) {
    return window.fetch(`/api/updatePlayer/${oldname}/${newname}`
, 
{
        method: 'PATCH'
    })
        .then(r => r.json());
}

function deletePlayer(name) {
    return window.fetch(`/api/deletePlayer/${name}`, {
        method: 'DELETE'
    })
        .then(r => r.json());
}

export default {
    getTeam,
    updatePlayer,
    addPlayer,
    deletePlayer
}

Now let us see our application in action.

5. Running the application

To run our application we need to run the following command

/my-app>npm start

This command as it is setup will launch both, our Server-side API as well as the ReactJS application using concurrently. The result should be as below:

ReactJS API Calls - Project Output
Project Output

This wraps up our look at API Calls example in a ReactJS Application.

6. Download the Source Code

Download
You can download the full source code of this example here: ReactJS API Calls Example

Siddharth Seth

Siddharth is a Software Development Professional with a Master degree in Computer Applications from IGNOU. He has over 14 years of experience. And currently focused on Software Architecture, Cloud Computing, JavaScript Frameworks for Client and Server, Business Intelligence.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button