How to make Axios Requests in React to a nodejs API

Interfering with a RESTful API to fetch and display data is an essential stage in your journey as a web developer, and the HTTP protocol is the most common way to communicate with your application backend. Making HTTP requests can be done in different ways, and using axois is one of them. In this article, we will discuss how to fetch responses from a node.js API and get ressouces using Axios inside a React apps.

Prerequisites

To follow along this article you need to have:

Why to use Axios

Axios is a popular promise-based client HTTP API dedicated to make http requests from node.js and XMLHttpRequests from the browser. The promise-based nature of axios gives us the ability to use and take advantage of the async/await combination to write more asynchronous code.

Axios requests

You can make an HTTP request simply by passing a config object to the axios function. the config object is an object of key/value pairs to specify the request method and the url. It also contains the data to send to the url in case of a POST, PUT, PATCH request, additional data and multiple options. It good to note that:

  • URL is the only required property of config object.
  • In case the method property is not specified in the config object, axios will use the default value which is the GET method

If you want to know more about the config object and its options click HERE.

// Example of a POST request
axios({
  method: 'post',
  url: 'https://yourAPIname.com/api/users',
  data: {
    userName: 'user1',
    userEmail: 'usermail@gmail.com'
  }
});



// Example of a GET request
axios({
  method: 'GET',
  url: 'https://yourAPIname.com/api/users',
  
}).then(response => {
    console.log(response.data);
  }, (error) => {
  console.log(error);
});

Axios Request method aliases

To simplify the request methods, axios provides aliases to all the supported methods. By using the following alias methods, you don’t have to specify the URL, method or data in the config object.

 axios.request(config)

 axios.get(url[, config])

 axios.delete(url[, config])

 axios.head(url[, config])

 axios.options(url[, config])

 axios.post(url[, data[, config]])

 axios.put(url[, data[, config]])

 axios.patch(url[, data[, config]])

Now, let’s write the precedents examples using the corresponding alias methods.

// Example of a POST request

axios.post('https://yourAPIname.com/api/users', {
  userName: 'user1',
  userEmail: 'usermail@gmail.com'
});




// Example of a GET request

axios.get('https://yourAPIname.com/api/users')
.then(response => {
    console.log(response.data);
  }, (error) => {
  console.log(error);
});

Axios Response

Once an HTTP request is made, Axios will return a promise. This promise can be resolved or rejected depending on the server response. To handle the response, we use the then() method with two callback functions as arguments.

  • If the promise is resolved, the first callback function argument will be called.
  • If the promise is rejected, the second callback function argument will be called.

In case the request was successful and the promise resolved, the response will contain the following information.

{
  // `data` is the response that was provided by the server
  data: {},

  // `status` is the HTTP status code from the server response
  status: 200,

  // `statusText` is the HTTP status message from the server response
  statusText: 'OK',

  // `headers` the HTTP headers that the server responded with
  // All header names are lower cased and can be accessed using the bracket notation.
  // Example: `response.headers['content-type']`
  headers: {},

  // `config` is the config that was provided to `axios` for the request
  config: {},

  // `request` is the request that generated this response
  // It is the last ClientRequest instance in node.js (in redirects)
  // and an XMLHttpRequest instance in the browser
  request: {}
}

The following code is a simple example of how to handle response using then() method with GET method:

// Example of handling response using then() 

axios.get('https://yourAPIname.com/api/users')
.then(response => {
    console.log(response.data);  // first function the get the dada provided by the server
  }, 
(error) => {
  console.log(error);  // second function handle the error and log it to the console
});

Axios features

Beside the wide browser support and the features already mentioned, Axios provides several useful features which make it powerful over other methods:

1- Automatic transforming of JSON data

While using Axios, you don’t need to parse the results of your HTTP requests with .json method because Axios By default, automatically converts requests and responses to JSON data.

2- Transform request and response data

In case you are working with an API which accepts only a specific format such as XML or CSV, you can change the default behavior (Automatic transforming of JSON data)and define another transformation mechanism. You can do that by using transformRequest and transformResponse properties of the config object.

  • transformRequest: this property is used to change the request data of PUT, POST and PATCH methods and takes data and headers as arguments.
const options = {
  method: 'post',
  url: 'https://yourAPIname.com/api/users',
  data: {
    userName: 'user1',
    userEmail: 'usermail@gmail.com'
  },
  transformRequest: [(data, headers) => {
    // transform the data

    return data;
  }]
};

// send the request
axios(options);


  • transformResponse: this property is used to change the responses data before to pass it to then() and catch() and takes response data as argument.
const options = {
  method: 'post',
  url: 'https://yourAPIname.com/api/users',
  data: {
    userName: 'user1',
    userEmail: 'usermail@gmail.com'
  },
  transformResponse: [(data) => {
    // transform the response

    return data;
  }]
};

// send the request
axios(options);

3- Axios interceptors

intercepting HTTP requests and responses is an important feature of Axios that allows developers to modify and change the request before Axios sends it, or transform the response before Axios returns the response to your code.

Axios interceptors are defined as functions to execute implicit tasks such as authentication and authorization. These functions are called for every request or response so you don’t have to write separate code for each HTTP request and they receive the entire response object or request and request config as arguments.

3-1 Request interceptors

Request interceptors usually used to set the authorization header. The following code represents a simple example of request interceptor. The axios.interceptors.request.use() prints “request was sent” to the console and send a token in authorization header So axios will call the request interceptor before each request that means print the “request was sent” message and send the token within each HTTP request.

// Request interceptor example

axios.interceptors.request.use(req => {
  console.log("request was sent");
  req.headers.authorization = 'token';
  return req;
});


axios.get('https://yourAPIname.com/api/users').then(response => {
    console.log(response.data);
  });



3-2 Response interceptors

Response interceptors are used to transform the response object on its way back to the application and to handle errors in a different way than the Axios default error message with a status code 404. The axios.interceptors.response.use() takes two functions as parameters. The first one return the response in case of success and the second one handle the error in case the request failed.

// Response interceptor example

axios.interceptors.response.use(
(response) => {
  // This is the first function parameter
  console.log('Response was received');
  return response;

}, error => {
  // this is the second function parameter to handle error
  if (err.response.status === 404) {
      throw new Error(`Your new error message`);
    }
    throw err;
  }

});


axios.get('https://yourAPIname.com/api/users')
.then(response => {
    console.log(response.data);
  });

4- Axios Cancel Request

In case you want to clean up and cancel all requests when a user navigates to another page, Axios offers the feature of canceling request by using a cancel token. Note that you can cancel a request only if it has not yet been sent over the network to the server.

To get the cancel token and cancel a request you can follow these steps:

  • First, pass the cancelToken option to your Axios request and get the source object.
  • Then, get the token from the source object.
  • Pass this token as cancelToken option to your Axios request.
  • Finally, call the source.cancel() function and pass to it an optional error message to explain the cancellation reason.
const source = axios.CancelToken.source();
const cancelToken = source.token;

const req = axios.get('https://yourAPIname.com/api/users', {
  cancelToken
}).catch(error => {
  if (axios.isCancel(error)) {
    console.log(error);
  } else {
    // you can handle the error here
  }
});

source.cancel('The reason of cancellation');

5- Client-side support for protection against XSRF

This feature allows you to improve your protection against XSRF (Cross-site request forgery) attacks by offering the possibility of adding authentication data in axios requests. This additional data will be used by the server in the authorization process.

The following code shows an example of adding xsrfCookieName and xsrfHeaderName in the Axios request:

const options = {
  method: 'post',
  url: 'https://yourAPIname.com/api/users',
  data: {
    userName: 'user1',
    userEmail: 'usermail@gmail.com'
  },
  xsrfCookieName: 'XSRF-TOKEN',
  xsrfHeaderName: 'X-XSRF-TOKEN',
};

// send the request
axios(options);

6- Simultaneous requests

Axios offers another interesting and useful feature, which is the ability to make multiple and parallel request by using the axios.all() and axios.spread() methods.

  • The axios.all() method takes an array of requests as argument and return response array for resolved promise only if all the requests passed in the array have resolved.
  • the axios.spread() is used to assign the values of the response array to separate variables.
axios.all([
  axios.get('https://yourAPIname.com/api/users/:user1Id'),
  axios.get('https://yourAPIname.com/api/users/:user2Id')
])
.then(axios.spread((user1, user2) => {
  console.log(user1.data);
  console.log(user2.data);
}));


How to make Axios requests in React app

React is a JavaScript framework for building frontend applications. In order to make these applications able to send and receive data, we need to implement for them a functional backend RESTful API. Having a server app to communicate with upgrade the react app to be full stuck application. The communication between the two parts is usually done via the http protocol, and there are various ways to do that.

If you’d like to learn more about React full stack applications, check out these links:

Requesting data from a node.js API can be done in different ways, and axios is one of them. Like we said earlier, axois is a JavaScript library promise based to make HTTP requests from nodejs. In the rest of this article, we will explore and explain how to use Axios inside a React application to create HTTP requests and handle responses by following these steps:

Step1: Axios Installation

Axios is not a native JavaScript API, so the first step to use axios is installing it by running one of these commands in your existing React application.

 $ npm install --save axios

OR

 $ yarn add axios

Once the installation is done, import axois into the React Component where you want to use it by adding the following code line :

import axios from 'axios';

Step2: Make Axios requests in React

Usually HTTP requests made with axios are done in React Components. If your component is a traditional Class Component, then lifecycle methods are the perfect place to make your requests. Otherwise, if you are using a Functional Component, you can write your HTTP requests inside useEffect() react hook.

For more informations on React Lifecycle see: What is Component Lifecycle in React.

1- Axios requests in React Class Component

Example of GET request using axios in Class Component

One of the most common request is retrieve and load data when component mounts or when page renders. componentDidMount() lifecycle is the perfect place to make this requests.

First, you import React and Axios in the component. Then make your GET request inside the componentDidMount lifecycle hook to retrieve the employees list and response status from the URL: https://yourAPIapp.com/api/employees.

Next update the employees array using this.setState() and display the employees list by rendering Employee component for each employee in the employees array.

// Example of axios GET request in EmployeesList component

import React from 'react';
import Employee from './Employee';
import axios from 'axios';


class  EmployeesList extends React.Component {

    constructor(props) {
        super(props);
        this.state={
            employees: []   
        } ;

    }

    componentDidMount(){
        
      axios.get('https://yourAPIname.com/api/employees')
     .then(res => {
         console.log(res.data.status);
         this.setState({employees: res.data.employees});
         })
    }

 
 renderMap(){
    
     const employees = this.state.employees;
    if(employees){
        return employees.map(employee =>{ return <Employee key={employee.id} employee= {employee} >})
    }
}



    render(){
    return (
       <div className="container-fluid ">
           <div className="pb-2 pt-2">
           {this.renderMap()}
           </div>
    );
    }
}


export default EmployeesList;

Example of POST request using axios in Class Component

The code below sends an HTTP POST request from your React app to your API. this example adds an employee object to the ‘https://yourAPIname.com/api/employees’ route and then get the updated employees list.

import React from 'react';
import { Form, Col } from 'react-bootstrap';
import axios from 'axios';




class AddEmployeeForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      name: '',
      position: '',
      wage: 0
    };

    this.handleAddEmployeeSubmit = this.handleAddEmployeeSubmit.bind(this);
    
  }


  handleAddEmployeeSubmit = (event) => {
    event.preventDefault(); // to prevent refreshing the page every time we submit 

      axios.post('https://yourAPIname.com/api/employees', { employee: this.state })
        .then(res => {
          console.log(res.status);
          console.log(res.data);
          
        });
    } 

  

  render() {
    return (
      <div className="container py-5 bg-grey">
        <Form className="form-add" onSubmit={this.handleAddEmployeeSubmit} >
         
         // Add your add form here

        </Form>

      </div>
    );
  }
}


export default AddEmployeeForm;

Example of PUT request using axios in Class Component

This example will show you how to update a specific employee using the axios PUT request with the employee ID.

import React from 'react';
import { Form } from 'react-bootstrap';
import axios from 'axios';


class UpdateEmployeeForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      name: '',
      position: '',
      wage: 0
    };

    this.handleUpdateEmployeeSubmit = this.handleUpdateEmployeeSubmit.bind(this);
    
  }



  handleUpdateEmployeeSubmit = (event) => {

    event.preventDefault(); // to prevent refreshing the page every time we submit. 

    
      axios.put('https://yourAPIname.com/api/employees/${this.props.employee.id}', { employee: this.state })
        .then(res => {
          console.log(res.status);
        });
    
  }

  

  render() {
    return (
      <div className="container py-5 bg-grey">
        <Form className="form-update" onSubmit={this.handleUpdateEmployeeSubmit} >
          // add your update form here
        </Form>

      </div>
    );
  }
}


export default UpdateEmployeeForm;

Example of DELETE request using axios in Class Component

In this example, you will see how to delete a specific employee using axios delete request with an employee ID: this.props.employee.id and return the status of your request.

// DELETE example in Employee Component
import React from 'react';
import axios from 'axios';


class Employee extends React.Component {
    


    deleteEmployee=(id)=>{
       
        axios.delete('https://yourAPIname.com/api/employees/${id}')
        .then(res =>{
            console.log(res.status); 
              
        });
    }


 
    render(){

    return (
        <div  className="container-fluid text-center    d-lg-block">
            <div className="row">
                <div className="col-10 mx-auto col-lg-2">
                    <p className="text-uppercase">{this.props.employee.name} </p>
                </div>
                <div className="col-10 mx-auto col-lg-2">
                    <p className="text-uppercase">{this.props.employee.position}</p>
                </div>
                <div className="col-10 mx-auto col-lg-2">
                    <p className="text-uppercase">{this.props.employee.wage}</p>
                </div>
                <div className="col-10 mx-auto col-lg-2">
                <i className="fas fa-trash remove-icon " onClick={()=>{this.deleteEmployee(this.props.employee.id); }}/>
                </div>
        
        </div>
      
    );
    }
}

export default Employee;

2- Axios Requests in React Functional Component

When using react functional component, we write our HTTP requests in useEffect react hook instead of componentDidMount lifecycle method to get data when the component loads.

Example of GET request using axios in useEffect() React hook

// Example of axios GET request in EmployeesList function Component

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

const EmployeeList = (props) => {
  const [employees, setEmployees] = useState([]);

  

useEffect(() => {
    
    axios.get('https://yourAPIname.com/api/employees')
     .then(res => {
         
         console.log(res.data.status);
         setEmployees(res.data.employees);
         })

}, []); // the empty array means this effect will only run once like componentDidMount in classes

return(
//display your list here
   );
}


export default EmployeesList;

Example of POST request using axios in React Functional component

// import useState from react.

import React, { useState } from 'react';
import { Form, Col } from 'react-bootstrap';
import axios from 'axios';




const AddEmployeeForm (props) =>{
const  [employee, setEmployee] = useState({name: '',
      position: '',
      wage: 0
    });



  const handleAddEmployeeSubmit = (event) => {
    event.preventDefault(); // to prevent refreshing the page every time we submit message

      axios.post('https://yourAPIname.com/api/employees',  employee )
        .then(res => {
          console.log(res.status);
          console.log(res.data);
          
        });
    } 
//here you handle changes and update employee const using setEmployee

return (
      
         // Add your add form here .
        
    );
  
}


export default AddEmployeeForm;

Example of PUT request using axios in React Functional component

// import useState from react.

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


const UpdateEmployeeForm (props) {

const  [employee, setEmployee] = useState({name: '',
      position: '',
      wage: 0
    });
  



  const handleUpdateEmployeeSubmit = (event) => {

    event.preventDefault(); // to prevent refreshing the page every time we submit.

    
      axios.put('https://yourAPIname.com/api/employees/${props.employee.id}', employee)
        .then(res => {
          console.log(res.status);
        });
    
  }

  //add handle changes and update employee const using setEmployee.


 
    return (
      
          // add your update form here.
 
    );
  
}


export default UpdateEmployeeForm;

Example of DELETE request using axios in React Functional component

// DELETE example in Employee Functional Component

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


const Employee (props) {
    


 const deleteEmployee=(id)=>{
       
        axios.delete('https://yourAPIname.com/api/employees/${id}')
        .then(res =>{
            console.log(res.status); 
              
        });
    }


 
    

    return (
        <div  className="container-fluid text-center    d-lg-block">
            <div className="row">
                <div className="col-10 mx-auto col-lg-2">
                    <p className="text-uppercase">{this.props.employee.name} </p>
                </div>
                <div className="col-10 mx-auto col-lg-2">
                    <p className="text-uppercase">{this.props.employee.position}</p>
                </div>
                <div className="col-10 mx-auto col-lg-2">
                    <p className="text-uppercase">{this.props.employee.wage}</p>
                </div>
                <div className="col-10 mx-auto col-lg-2">
                <i className="fas fa-trash remove-icon " onClick={deleteEmployee(props.employee.id)}/>
                </div>
        
        </div>
      
    );
    
}

export default Employee;

3- How to use async/await with axios

Another thing the promise-based nature of axios allows us to do is take advantage of async and await. When using async/await functions, you don’t no need to use .then() method because await expression will allow the program execution to wait until the promise is resolved and return the promise value.

Axios GET request using async/await and error handling

The code below shows how to use async/await combination in an axios get request and handle the error using the try{…} catch.

// GET request using async/await and handling error using try catch.


async componentDidMount(){
        try{
      const response= await axios.get('https://yourAPIname.com/api/employees');
     
         console.log(response.data.status);
         this.setState({employees: response.data.employees});
        
       } catch (err) {
        console.log(err);
       // handle the error here.
      }
        
    }


Axios POST request using async/await and error handling

// POST request using async/await and handling error using try catch.

handleUpdateEmployeeSubmit = async (event) => {

    event.preventDefault(); 

    try{
   const response= await 
    axios.put('https://yourAPIname.com/api/employees/${this.props.employee.id}', { employee: this.state });
        
          console.log(response.status);
    
     } catch (err) {
        console.log(err);
       // handle the error here.
      }       
    
  }




Axios PUT request using async/await and error handling

// PUT request using async/await and handling error using try catch.
 
handleUpdateEmployeeSubmit = async (event) => {

    event.preventDefault(); 
    try{
     const response= await axios.put('https://yourAPIname.com/api/employees/${this.props.employee.id}', { employee: this.state });
          console.log(response.status);

        } catch (err) {
        console.log(err);
       // handle the error here.
      }       
    
  }

Axios DELETE request using async/await and error handling

// DELETE request using async/await and handling error using try catch.


deleteEmployee= async (id)=>{
       try{
        const response= await axios.delete('https://yourAPIname.com/api/employees/${id}')
            console.log(res.status); 
              
        } catch (err) {
        console.log(err);
       // handle the error here.
      }       
    }

Step3: Create Axios instance

Axios Instances is a functionality provided by axois to be specially used with React applications. They help to keep the code dry and provide a much simpler and cleaner app. It is commonly used in applications that are requesting API frequently to define baseURL, set custom headers, and other default elements. To learn more about instances configuration elements, check out HERE.

To create an axios instance, inside your application navigate to src directory, create a new file and name it for example: APIInstance.js and create your instance in it and define the API baseURL to avoid writing the whole API URL each time you make a new axois request.

// APIInstance.js


import axios from 'axios';

export default axios.create({
 //define baseURL for api.
  baseURL: 'https://yourAPIname.com/', 
// set HTTP headers for all requests.
  headers = {
        'Authorization': 'Bearer token'   
    }

});

Then import import the APIInstance.js by adding this line of code to your Components :

import  axoisApi from '../APIInstance.js';

So the example of GET request using axios in the EmployeesList Class Component will look like:

// Example of axios GET request in EmployeesList component using axios instance

import React from 'react';
import Employee from './Employee';

import  axoisApi from '../APIInstance.js';


class  EmployeesList extends React.Component {

    constructor(props) {
        super(props);
        this.state={
            employees: []   
        } ;

    }

    async componentDidMount(){
        try{
      const response= await axiosApi.get('/api/employees');
     
         console.log(response.data.status);
         this.setState({employees: response.data.employees});
        
       } catch (err) {
        console.log(err);
       // handle the error here.
      }
        
    }
 
 renderMap(){
    
     const employees = this.state.employees;
    if(employees){
        return employees.map(employee =>{ return <Employee key={employee.id} employee= {employee} >})
    }
}



    render(){
    return (
       <div className="container-fluid ">
           <div className="pb-2 pt-2">
           {this.renderMap()}
           </div>
    );
    }
}


export default EmployeesList;

Now you can use the same way to use the axios instance in all your React Components.

Conclusion

This article was a :

  • Good look at Axios and its features.
  • Depth explanation of how to use axios in React app.
  • Several practices and detailed examples of axios HTTP reuquest.
Translate »