I want to intercept responses from all AJAX calls in my app. I want to check the status code and show a generic message based on error code. What's the best way to do this?
In this case I would suggest to use the fetch API along with an abstraction layer/ wrapper function.
Fetch API is promise based, so you can use better error catching as the fetch promise fails only when there is some error with Request or Network failure.
And rest of the things are passed on to the subsequent chain of promise.
So the code will look like following:
// file: services/remote-api.js
// or some similar file name
const fetch = require('whatwg-fetch');
const request = (url, params = { method: 'GET' }) => {
if (typeof url === 'string') {
return fetch(url, params);
}
// URL is a Request object, params are not needed
return fetch(url);
}
request.then(response => {
if (response.responseCode === 200) {
// return response.json(); // in case of JSON API
return response.body();
}
// handle other 2XX
// 201 is for resource created which is a succesful request
// Add more cases for the error handling like 4XX, 5XX etc
// alert(response.responseCode);
console.warn(response);
})
request.catch(excption => {
// alert(exception.message);
console.error(exception)
});
module.exports = request;
Now just import this file and use the imported function; all error handling is in the above file. Like ex:
const api = require('services/remote-api');
const url = 'jsonplaceholder.typicode.com/posts';
// GET request
api(url).then(console.log)
// POST request
const headers = new Headers(); // attach needed ones like of CORS
const form = new FormData();
form.append('name', 'Time to Hack');
form.append('url', 'time2hack.com');
const request = new Request(url, {
method: 'POST',
headers: headers,
body: form
});
api(request).then(data => console.log);
Most pieces of examples are taken from time2hack.com/2017/11/goodbye-xmlhttprequest-ajax…
I have to go Madurai Hospital of Neurology. I can't believe your on your answer.
Marco Alka
Software Engineer, Technical Consultant & Mentor
Yes, it's possible. Let me explain with an example. Here we have a simple AJAX call:
function loadDoc() { let xhttp = new XMLHttpRequest(); xhttp.onreadystatechange = () => { if (this.readyState == 4 && this.status == 200) { document.getElementById("demo").innerHTML = this.responseText; } }; xhttp.open("GET", "ajax_info.txt", true); xhttp.send(); }The call is made by creating a new object from
XMLHttpRequestand then the object is used for everything. You would have to tap into the object created there in order to intercept the call. That's usually not possible. What you can do, however, is proxy the point at which that object is created, so that you control what extra stuff the object does in certain situations:// we have to overwrite the original XMLHttpRequest with our own version of it XMLHttpRequest = class extends XMLHttpRequest {// by extending, we copy over all the original functionality send() { // we overwrite the send function // then we proxy the onreadystatechange property this._onreadystatechange = this.onreadystatechange; this.onreadystatechange = () => { // Do your stuff here! console.log('Ready State: ' + this.readyState); if (typeof this._onreadystatechange === 'function') { this._onreadystatechange();// call original event handler } }; super.send();// finally, we call the original send function }; };Done and tested on Hashnode :) Remember, though, this is a hackaround and it won't work in certain situations (like, when you set the
onreadystatechangeproperty aftersend()in your normal AJAX request code. I do not know of any better solution