Axios helper file with interceptors, how to turn it into a context provider?

I have an Axios helper file I have created to add interceptors to my Axios instance. The problem is I am making a hook call in there: const { instance } = useMsal(); and after some research, I have learned you cannot do that outside of a functional component. So now I think from digging more into this, the only way is to make a Axios provider and wrap my app in that? Is that the best way? If so, how do I do that? Here is the code in my Axios file:
import axios from 'axios';
import { useMsal} from '@azure/msal-react';

const serverURL =
import.meta.env.MODE === 'development'
? 'http://localhost'
: import.meta.env.VITE_BASE_URL;

const middlePart = import.meta.env.VITE_API_PATH;

const axiosInstance = axios.create(
{baseURL:serverURL + middlePart + '/'}
);

const { instance } = useMsal(); // <-- here is the culprit hook
const tokenRequest = {
account: instance.getActiveAccount(), // This is an example - Select account based on your app's requirements
scopes: [import.meta.env.VITE_QUOTES_API_SCOPE]
};
import axios from 'axios';
import { useMsal} from '@azure/msal-react';

const serverURL =
import.meta.env.MODE === 'development'
? 'http://localhost'
: import.meta.env.VITE_BASE_URL;

const middlePart = import.meta.env.VITE_API_PATH;

const axiosInstance = axios.create(
{baseURL:serverURL + middlePart + '/'}
);

const { instance } = useMsal(); // <-- here is the culprit hook
const tokenRequest = {
account: instance.getActiveAccount(), // This is an example - Select account based on your app's requirements
scopes: [import.meta.env.VITE_QUOTES_API_SCOPE]
};
Rest of the code is pasted below.
UU
Unknown User97d ago
D
dmikester197d ago
Here is the rest of that code from above:
let result: { accessToken: string }, msalError: string;
axiosInstance.interceptors.request.use((config) => {
config.headers['request-startTime'] = new Date().getTime();

instance
.acquireTokenSilent(tokenRequest)
.then((response) => {
// console.log({ response });
result = { accessToken: response.accessToken };
})
.catch((e) => {
console.log({ e });
msalError = e.message;
});

if(result && result.accessToken) {
const token = result.accessToken; //store.getState().session.token;
config.headers.Authorization = token;
}
return config;
});

axiosInstance.interceptors.response.use((response) => {
const currentTime = new Date().getTime();
const startTime = response.config.headers['request-startTime'];
response.headers['request-duration'] = currentTime - startTime;
return response;
});

export default axiosInstance;
let result: { accessToken: string }, msalError: string;
axiosInstance.interceptors.request.use((config) => {
config.headers['request-startTime'] = new Date().getTime();

instance
.acquireTokenSilent(tokenRequest)
.then((response) => {
// console.log({ response });
result = { accessToken: response.accessToken };
})
.catch((e) => {
console.log({ e });
msalError = e.message;
});

if(result && result.accessToken) {
const token = result.accessToken; //store.getState().session.token;
config.headers.Authorization = token;
}
return config;
});

axiosInstance.interceptors.response.use((response) => {
const currentTime = new Date().getTime();
const startTime = response.config.headers['request-startTime'];
response.headers['request-duration'] = currentTime - startTime;
return response;
});

export default axiosInstance;
D
dmikester197d ago
I did some more digging and found that there is a way to pass data into the axios interceptor when calling e.g. axios.get(...) => https://stackoverflow.com/a/70647045/571723
Stack Overflow
Pass parameter/argument to axios interceptor
How do I send custom parameters to the axios interceptor? I am using an interceptor like this: window.axios.interceptors.request.use(function (config) { if (PASSED_PARAM == true) {