Wednesday, October 16, 2019

Axios In Action

We all know that Axios is a promise-based HTTP client for the browser and node.js. Although I have used Axios extensively while making GET, POST request calls and multiple concurrent requests call from the front end, I have never used Axios in conjunction with node.js. Today we would be discussing how to use Axios for making any kind of calls from the front end and some other Axios related important stuff.

1. Introduction


Similar to traditional AJAX call, one could easily make Axios calls without much hustle from the front end. One needs to include below JS library in order to work it properly:
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
Today we would be touching on below items:
  • How to make Axios GET / POST calls?
  • How to make multiple concurrent requests calls?
  • How to handle the dependent request calls using Axios?
  • Understanding the response to a request
  • How to handle errors that occurred while making Axios calls?

2. GET Request


Performing a GET request:
// Make a request for a user with a given ID
axios.get('/getAssignment?id=12345')
  .then(function (response) { // handle success
    console.log(response);
  })
  .catch(function (error) {  // handle error
    console.log(error);
  })
  .finally(function () {  // always executed
   ...
  });
Optionally the above request could also be done as
axios.get('/getAssignment', {
    params: {
      id: 12345
    }
  })
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  })
  .then(function () {
    // always executed
  });  

3. POST Request


Performing a POST request:
axios.post('/saveAssignment', {
   'assignmentData' : assignmentData // an array containing: label,type,availableon,dueon etc
  })
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });
Obviously, @RequestMapping i.e. /saveAssignment would call one of our Controller's methods. Worried about how this data would be available in Controller layers? Don't worry? We got you covered here. Just look at the below code snippet:
@RequestMapping(value = "/saveAssignment", headers = "Content-Type=application/json", method = RequestMethod.POST)
@PreAuthorize("isAuthenticated()")
public ResponseEntity<String> saveAssignment(Model model, @RequestBody Map<String, String[]> assignmentDataMap) {

 String[] assignmentData = assignmentDataMap.get("assignmentData");
 ...
} 

4. Multiple concurrent requests


Performing multiple concurrent requests:
function findAssignmentById(assignmentId) {
 return axios.get("/getAssignment?id=" + assignmentId);
}

function findAllAssignmentUser(assignmentId) {
 return axios.get("/getAssignmentUsers?assignmentid=" + assignmentId);
}

axios.all([findAssignmentById(), findAllAssignmentUser()])
  .then(axios.spread(function (assignmentData, userData) {
    // Both requests are now complete
 var assignment = assignmentData.data;
 var users = userData.data;
  }));
Tips: Never use this, when the requests are dependent anyhow.

5. Multiple requests but dependent somehow


It may happen that depending upon the return value from one Axios call, one may require to make another Axios call conditionally. In those cases, one could follow the below approach.
var assignmentId1 = 1234;
axios.get("/getAssignmentUser?id="+assignmentId1).then(function(response) {    
 var assignmentUserFlag = response.data.size() > 0;
 if(assignmentUserFlag){
  axios.get("/getAssignment?id="+assignmentId1).then(function(response) { 
  
  }).catch(function (error) {
   ...
  });
 } else {
   ....
 }
}).catch(function (error) {
 ...
});

6. Understanding the response to a request 


The response to a request contains 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 headers that the server responded with
  // All header names are lower cased
  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 the browser
  request: {}
}
When using then, one will receive the response as follows:
axios.get('/getAssignment?id=12345')
  .then(function (response) {
    console.log(response.data);
    console.log(response.status);
    console.log(response.statusText);
    console.log(response.headers);
    console.log(response.config);
 });

7. Handling Errors


You must be thinking about why there is a separate section for this. From the start of this article, we have maintained that inside catch block i.e. ".catch(function (error) { ..}" we would handle the error, End of the Story right? But wait there is still more left to it. 
axios.get('/getAssignment?id=12345')
  .catch(function (error) {
    if (error.response) {
      // The request was made and the server responded with a status code
      // that falls out of the range of 2xx
      console.log(error.response.data);
      console.log(error.response.status);
      console.log(error.response.headers);
    } else if (error.request) {
      // The request was made but no response was received
      // `error.request` is an instance of XMLHttpRequest in the browser and an instance of
      // http.ClientRequest in node.js
      console.log(error.request);
    } else {
      // Something happened in setting up the request that triggered an Error
      console.log('Error', error.message);
    }
    console.log(error.config);
  });
Point to ponder: Before starting I would like to highlight that the above code snippet is taken from the official website. It's regarding "else if (error.request) {..}" block. It states that "The request was made but no response was received" obviously from the server. Now one open question to you - In Microservice Architecture, suppose service A is calling service B which is down (we have manually stopped it) then no doubt it would enter in catch block but where would the control go, if, else if or last else block? 
According to me, it should go inside else if block as the server is down(service B) but we have made the request properly. But to my surprise, it entered inside if block. But how can that happen when the server was down? How the server can respond? Just for information, in JS, we are getting Internal Server Error(500 status code) whereas in STS console, 404. If you have the answer to the above question or any logical explanation then please share in the comment section.

8. Conclusion


I hope that now you know how to use Axios. It would surely help you while doing development work using Axios. Happy Learning !! ☺

No comments:

Post a Comment