I am changing the result status of the Axios with an adapter to change the result status.
import axios, { AxiosAdapter, AxiosError, AxiosResponse } from "axios";
import httpAdapter from "axios/lib/adapters/http";
import settle from "axios/lib/core/settle";
const customAdapter = (config) =>
new Promise((resolve, reject) => {
httpAdapter(config)
.then(async response => {
const jsonResponse = JSON.parse(response.data);
if (jsonResponse.error) {
if (
jsonResponse.error.code === 12345
) {
response.status = 401;
} else {
response.status = 503;
}
}
settle(resolve, reject, response);
})
.catch(reject);
});
const apiInstance = axios.create({
baseURL:"/api"
});
apiInstance.defaults.adapter = customAdapter as AxiosAdapter;
export default apiInstance;
In new version of Axios, we don't have support for httpAdapter which was present in the 'axios/unsafe/adapters/http'. It is basically not exported from the package. (https://github.com/axios/axios/issues/5000#issuecomment-1521957205)
For this you have to use xhrAdapter.
import axios from "axios";
import xhrAdapter from "axios/unsafe/adapters/xhr";
import settle from "axios/unsafe/core/settle";
const apiInstance = axios.create({
adapter: config =>
new Promise((resolve, reject) => {
xhrAdapter(config)
.then(async response => {
const jsonResponse = JSON.parse(response.data);
if (jsonResponse.error) {
if (
jsonResponse.error.code === 12345
) {
response.status = 401;
} else {
response.status = 503;
}
}
settle(resolve, reject, response);
})
.catch(reject);
}),
baseURL: "/api"
});
YAY!! You resolved the issue now if you try to run this you will notice the paramserializer has been also changed which means the API the params will look something like
http://localhost:3000/api/store?input[request][method]=GetStoreType&input[request][args][0]=m%40d
Ideally it should be coming as
http://localhost:3000/api/store?input=%7B%22request%22%3A%7B%22method%22%3A%22GetStoreType%22%2C%22args%22%3A%5B%22mr%40d
Referred this article text and used below code:
axios.defaults.paramsSerializer = params =>
Object.keys(params)
.filter(key => params[key] !== undefined)
.map(key => {
if (Object.prototype.toString.call(params[key]) === "[object Object]") {
params[key] = JSON.stringify(params[key]);
}
if (Array.isArray(params[key])) {
return params[key].map((v: any) => `${key}[]=${encodeURIComponent(v)}`).join("&");
}
return `${key}=${encodeURIComponent(params[key])}`;
})
.join("&");
YAY!! Issue resolved. Now comes the test cases. When you run the test cases test suites will fail as jest will not find module 'axios/unsafe/adapters/xhr'.
Found one article regarding jest not working after upgrade (https://github.com/axios/axios/issues/5101)
After attempting the fixes mentioned in the (https://github.com/axios/axios/issues/5101)
1. "react-scripts test --transformIgnorePatterns \"node_modules/(?!axios)/\"",
Cannot find module 'axios/unsafe/adapters/xhr'
2. "jest": {
"moduleNameMapper": {
"axios": "axios/dist/node/axios.cjs"
}
},
RangeError: Maximum call stack size exceeded
Exception in PromiseRejectCallback:
/home/project/node_modules/axios/dist/node/axios.cjs:3088
return adapter(config).then(function onAdapterResolution(response) {
^
RangeError: Maximum call stack size exceeded
Exception in PromiseRejectCallback:
node:internal/process/promises:107
function promiseRejectHandler(type, promise, reason) {
^
You need provide a module mapper configuration for the not found modules: