How can I add an aditional header to global instance of Axios in a custom request?

Viewed 189

This is my global Axios

import axios from 'axios';
import { storage } from 'containers/login/utils/local-storage';

const token = storage.getToken();

const axiosInstance = axios.create({
  baseURL: process.env.REACT_APP_API_URL,
});

    axiosInstance.interceptors.response.use((response) => {
  response.config.headers = {
    Authorization: `Bearer ${token}`,
  };

  return response;
}, (error) => Promise.reject(error));

axiosInstance.interceptors.request.use((request) => {
  request.headers = {
    Authorization: `Bearer ${token}`,
  };

  return request;
}, (error) => Promise.reject(error));

export default axiosInstance;

In this request I need to add new header: invoiceLimit = `${-invoiceLimit}`

export const updateInvoiceLimit = async (
  invoiceLimit: string,
)
  : Promise<ReturnDataType> => {
  let result: ReturnDataType = {} as ReturnDataType;

  try {
    axios.defaults.headers.common.invoiceLimit = `${-invoiceLimit}`;
    result = await axios.put(`${CREDITS_URL.CREDITS}/invoice/limit`);
   
    return result;
  } catch (error) {
    SnackBarUtils.error(`${(error as Error).message}. ${result.data.message}`);
  }

  return result;
};

When I use this: axios.defaults.headers.common.invoiceLimit = `${-invoiceLimit}`;

header adds to the Axios defaults, but then when I call axios.put so this custom header goes away and left only global header from interceptors.

I know it's not best practice, but its customer API and I want not to make another instance of Axios but use one global instance.

2 Answers

I think the problem is here:

axiosInstance.interceptors.request.use((request) => {
  request.headers = {
    Authorization: `Bearer ${token}`,
  };

  return request;
}, (error) => Promise.reject(error));

You are overriding all request headers with just this one:

{ Authorization: `Bearer ${token}` }

So try spreading headers before adding the new one like this:

axiosInstance.interceptors.request.use((request) => {
  request.headers = {
    ...request.headers,
    Authorization: `Bearer ${token}`,
  };

  return request;
}, (error) => Promise.reject(error));

Did this solve the problem?

I thought you could just reuse the initial axiosInstance and the headers will be merged when you do:

await axios.put(`${CREDITS_URL.CREDITS}/invoice/limit`,{}, {
  headers: {
    invoiceLimit: `${-invoiceLimit}`
  }
})
Related