ReactJS (HTTP/AJAX): Asynchronous Interaction between React application and Server (REST API with axions)

React application interaction with server to fetch data and submitting data to server is very common for any enterprise web application. Like any application react application requires HTTP Library to interact with server. We have HTTP library available some are promise based and some are callback based. Fetch and Axios are promised based HTTP library and Superagent is callback based HTTP library.

In this post I will use Axios for executing HTTP methods like GET and POST. In order to simply server side setup I have used Firebase Realtime Database. Firebase deals with JSON data and persist it in tree structure.

HTTP call in React component life cycle: componenetDidMount() is right place from where HTTP methods are executed with precaution do not update state as it will trigger re-rendering cycle and HTTP call be executed in infinite loop.

Prerequisite

1. Install and setup axios
2. Setup Firebase real time database & sample data setup

Install axios
$ npm install axios

Firebase setup: Create a sample project at Firebase(Spark mode is free). I have created project "react-devinline". Under database tab -> create Realtime Database "devinlineaction". Firebase generates URL https://devinlineaction.firebaseio.com/ which act as end point to access data from Firebase realtime database.

Under Rules tab update read and write access. It makes data access without auth and prevents error like "Failed to load resource: the server responded with a status of 401 (Unauthorized)"
{
  "rules": {
    ".read": true,
    ".write": true
  }
}. 

Import below JSON data in Firebase database devinlineaction
 {
  "orders": [
    {
      "orderNo": "3330047777379",
       "status": "Delivered",
      "customerInfo": {
        "customerId": "832edb65-6ea2-40e4-bb07-8c3a2bacc159",
        "primaryContact": {
          "name": {
            "firstName": "Nikhil",
            "lastName": "Ranjan"
          },
          "phone": {
            "completeNumber": "408-660-5027"
          },
          "email": {
            "emailAddress": "nikhilranjan@email.com"
          }
        },
        "address": {
          "addressLineOne": "655 S Fair Oaks Avenue",
          "addressType": "RESIDENTIAL",
          "city": "Sunnyvale",
          "countryCode": "USA",
          "postalCode": "94086",
          "state": "CA"
        }
      },
      "orderLines": [
        {
          "productName": "Fujifilm Instax Mini 7S Instant Camera (with 10-pack film) - Light Blue",
          "lineno": 1,
          "orderedQty": {
            "unitOfMeasure": "EA",
            "measurementValue": 1
          },
          "unitPrice": {
            "currencyAmount": 125,
            "currencyUnit": "USD"
          }
        },
        {
          "productName": "Sumsung Monitor 45' ",
          "lineno": 1,
          "orderedQty": {
            "unitOfMeasure": "EA",
            "measurementValue": 1
          },
          "unitPrice": {
            "currencyAmount": 305,
            "currencyUnit": "USD"
          }
        },
        {
          "productName": "Wirelss mouse Dell-UQA765",
          "lineno": 1,
          "orderedQty": {
            "unitOfMeasure": "EA",
            "measurementValue": 2
          },
          "unitPrice": {
            "currencyAmount": 25,
            "currencyUnit": "USD"
          }
        }
      ]
    },
    {
      "orderNo": "3330047777380",
       "status": "Shipped",
      "customerInfo": {
        "customerId": "832edb65-6ea2-40e4-bb07-8c3a2bacc159",
        "primaryContact": {
          "name": {
            "firstName": "Nikhil",
            "lastName": "Ranjan"
          },
          "phone": {
            "completeNumber": "408-660-5027"
          },
          "email": {
            "emailAddress": "nikhilranjan@email.com"
          }
        },
        "address": {
          "addressLineOne": "655 S Fair Oaks Avenue",
          "addressType": "RESIDENTIAL",
          "city": "Sunnyvale",
          "countryCode": "USA",
          "postalCode": "94086",
          "state": "CA"
        }
      },
      "orderLines": [
        {
          "productName": "Purell Advanced - 8 fl Oz",
          "lineno": 1,
          "orderedQty": {
            "unitOfMeasure": "EA",
            "measurementValue": 1
          },
          "unitPrice": {
            "currencyAmount": 10,
            "currencyUnit": "USD"
          }
        },
        {
          "productName": "Mask-12 pc",
          "lineno": 1,
          "orderedQty": {
            "unitOfMeasure": "EA",
            "measurementValue": 1
          },
          "unitPrice": {
            "currencyAmount": 12,
            "currencyUnit": "USD"
          }
        }
      ]
    }
  ]
}

HTTP GET API using axios

Create a class based component "Orders.js" and a functional component "Order.js". Class based component Orders executes GET API and displays orders in UI using Order functional component.

[Orders.js]- Class based component which manages state. orderStatus fetches order# and status & using Order component data are displayed.

import React, { Component } from 'react';
import axios from 'axios';

import Order from './Order';

class Orders extends Component {
    state = {
        ordersStatus: [],
        error: false
    }

    deleteDataHandler = (_orderNo) => {  
    }

    componentDidMount() {
        let ordernoAndStatus = []
        axios.get('https://devinlineaction.firebaseio.com/orders.json' )
            .then(res => {
                const fetchedOrders = [];
                for (let key in res.data) {
                    let orderNo = res.data[key].orderNo;
                    let status = res.data[key].status;
                    ordernoAndStatus.push({orderNo,status})
                    fetchedOrders.push({
                        ...res.data[key],
                        id: key
                    });
                }
                this.setState({ordersStatus : ordernoAndStatus});
                console.log(fetchedOrders);
            })
            .catch(err => {
                this.setState({loading: false});
            });
            
    }

    render () {
        let orders = <p style={{textAlign: 'center'}}>
            Opps!! Something went wrong.</p>;
        if (!this.state.error) {
            orders = this.state.ordersStatus.map(orderStat => {
                return <Order 
                    key={orderStat.orderNo}
                    orderNo={orderStat.orderNo} 
                    status={orderStat.status}
                    deleteHandle=
                        {this.deleteDataHandler(orderStat.orderNo)} />;
            });
        }
        return (
            <div>
                <section>
                    <h1> Get API using axios: Orders status</h1>
                    {orders}
                </section>
            </div>
        );
    }
}

export default Orders;

[Order.js] - Order component is functional/presentational component to generate UI with order# and status. Based on status Cancel order button is displayed (if order is delivered -> button is not displayed)
import React from 'react';

const order = (props) => (
    <div>
            <h3>{props.orderNo}</h3>
            {props.status}
            {props.status !== 'Delivered' ? <div><button 
                style={{ background: '#f44336', 
                         border: 'none',
                         color: 'white',
                         padding: '8px 5px',
                         fontSize: '20px',
                         cursor:'pointer',
                         }} 
                onClick={props.deleteHandle}>Cancel Order</button></div> : null}
     <div style={{width: '700px',
                    margin:'auto',
                    height: '7px',
                    borderBottom: '1px solid black'}}></div>
     </div>
     
);

export default order;


[App.js]
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';

import Orders from './containers/Orders'
import NewOrder from './components/NewOrder';

class App extends Component {
  
  render() {
    console.log('[App.js] render() execution');
    return (
      <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <h1 className="App-title">Welcome to React</h1>
        </header>

        {/* Render Child component Checkout */}
        <Orders/>
        <NewOrder/>
      </div>
    );
  }

}

export default App;


Start server using command : $ npm start and open http://localhost:3000/.
UI displaying order# and status & Console displaying GET Response

HTTP POST API using axios

[NewOrder.js] - HTTP Post method is executed on clicking create new Order button.

import React, { Component } from 'react';
import axios from 'axios';

class NewOrder extends Component {
    postDataHandler = () => {
        const data = {
            "orderNo": "3330047777381",
            "status": "Processing",
            "customerInfo": {
              "customerId": "832edb65-6ea2-40e4-bb07-8c3a2bacc159",
              "primaryContact": {
                "name": {
                  "firstName": "Nikhil",
                  "lastName": "Ranjan"
                },
                "phone": {
                  "completeNumber": "408-660-5028"
                },
                "email": {
                  "emailAddress": "nikhilranjan@email.com"
                }
              },
              "address": {
                "addressLineOne": "655 S Fair Oaks Avenue",
                "addressType": "RESIDENTIAL",
                "city": "Sunnyvale",
                "countryCode": "USA",
                "postalCode": "94086",
                "state": "CA"
              }
            },
            "orderLines": [
              {
                "productName": 
                    "Garmin vivoactive 3 Black with Stainless Hardware",
                "lineno": 1,
                "orderedQty": {
                  "unitOfMeasure": "EA",
                  "measurementValue": 1
                },
                "unitPrice": {
                  "currencyAmount": 149,
                  "currencyUnit": "USD"
                }
              }
            ]
          };
        axios.post('https://devinlineaction.firebaseio.com/orders.json', data)
            .then(response => {
                console.log(response);
                alert("Order Placed successfully !!")
            });
    }

    render () {
        return (
            <div>
                <h1> Post using axios: Place new order</h1>
                <button 
                    style={{ background: '#008CBA', 
                         border: 'none',
                         color: 'white',
                         padding: '15px 32px',
                         fontSize: '20px',
                         cursor:'pointer',
                         }} 
                    onClick={this.postDataHandler}>Create new Order</button>
            </div>
        );
    }
}

export default NewOrder;

Successful execution server respond with status code = 200

After refreshing UI - 3 orders are displayed in UI and Firebase database can be validated for new record.
Axios HTTP library can be used to execute DELETE,HEAD and PUT methods. It provides flexibility to configure request sent to server and handle server response. Error handling is also supported with axios.

11 Comments

  1. Thanks for sharing this, I actually appreciate you taking the time to share with everybody.
    Data Science Courses

    ReplyDelete
    Replies
    1. The article provides a clear introduction to handling asynchronous communication between a React application and a server through REST APIs. Using Axios for GET and POST requests, along with Firebase Realtime Database as the server-side data source, makes the example practical for understanding how React applications fetch and submit JSON data.

      The discussion of componentDidMount() is particularly useful because it shows where HTTP requests can be initiated in a React component lifecycle. Developers who want to build stronger React fundamentals can explore ReactJS Course in Chennai while practicing concepts such as component lifecycle methods, asynchronous requests, and API integration.

      Delete
    2. Axios is a convenient choice when an application needs promise-based HTTP communication, especially for common operations such as retrieving and submitting data. Working through practical examples with React Native Course in Chennai can also help developers understand how similar JavaScript concepts extend into mobile application development.

      Delete
  2. Thank you so much for exploring the best and right information.

    Informatica Read Rest API

    ReplyDelete
    Replies
    1. The article also highlights an important consideration when working with component state: updating state carelessly during the HTTP lifecycle can trigger additional rendering and potentially repeated requests. Applying these concepts to practical development scenarios through ReactJS Projects can provide useful hands-on experience with REST APIs, asynchronous interactions, and data-driven React applications.

      Delete
  3. Such a very useful article. Very interesting to read this article.I would like to thank you for the efforts you had made for writing this awesome article.


    DevOps Training in Hyderabad

    ReplyDelete
  4. ReactJS makes server communication much smoother by handling HTTP requests asynchronously, allowing applications to update data without reloading the entire page. Using REST APIs with Axios is a practical way to manage this interaction and keep the user experience responsive. The approach also makes it easier to organize data fetching and error handling within a React application. The explanation is clear and useful, especially for developers learning asynchronous communication. I also found Kamil Babar relevant in this discussion.

    ReplyDelete
Previous Post Next Post