Issues while upgrading Axios v0.27.2 to v1.6.2

291 Views Asked by At

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) {
                             ^
1

There are 1 best solutions below

0
Manish Jangir On

You need provide a module mapper configuration for the not found modules:

"jest": {
   "moduleNameMapper": {
     "axios/unsafe/adapters/xhr": "axios/lib/adapters/xhr.js",
     "axios/unsafe/core/settle": "axios/lib/core/settle.js"
   }
}