For my nextJS APP i am configuring the headers using axios interceptors:
import axios, { AxiosInstance, AxiosResponse } from "axios";
const httpClient: AxiosInstance = axios.create();
export const X_WORKSPACE_ID = "x-workspace-id";
export const X_APP_ID = "x-app-id";
let requestInterceptorId: number | null = null;
let responseInterceptorId: number | null = null;
export const setHttpClient = (
logout: () => void,
onError: (message: string) => void,
workspaceId?: string | string[],
appId?: string | string[]
) => {
console.log("REQUESTINTERCEPTOR: ", requestInterceptorId);
if (requestInterceptorId !== null) {
httpClient.interceptors.request.eject(requestInterceptorId);
console.log("Ejecting request interceptor");
}
if (responseInterceptorId !== null) {
httpClient.interceptors.response.eject(responseInterceptorId);
console.log("Ejecting response interceptor");
}
responseInterceptorId = httpClient.interceptors.response.use(
(response: AxiosResponse) => response,
(error) => {
if (error?.response?.status === 500) {
const { data } = error.response;
if (data) {
onError(data.message);
return Promise.reject(new Error(data.message));
}
}
if (error?.response?.status === 401 || error?.response?.status === 403) {
logout();
}
return Promise.reject(error);
}
);
console.log("WORKSPACEID:", workspaceId);
requestInterceptorId = httpClient.interceptors.request.use((config) => {
console.log("changing headers: ", workspaceId, appId);
config.headers = {
[X_WORKSPACE_ID]: workspaceId as string,
[X_APP_ID]: appId ? String(appId) : String(workspaceId),
};
console.log("CONFIG-HEADERS: ", config.headers);
return config;
});
};
export const appHttpService = httpClient;
I am then calling the setHttpClient with this hook:
import { useEffect } from "react";
import { useRouter } from "next/router";
import { useLogout } from "./useLogout";
import { setHttpClient } from "../../config/auth/appHttpService";
import { useAppDispatch } from "../../hooks/useAppDispatch";
import { setNotificationDescription } from "../notificationsSlice";
import { useAppId } from "../../hooks/useAppId";
export const useHttpClientSetup = () => {
const { logout } = useLogout();
const {
query: { workspaceId },
} = useRouter();
const { appId } = useAppId();
const dispatch = useAppDispatch();
const onError = (errorMessage: string) => {
if (errorMessage) {
dispatch(setNotificationDescription(errorMessage));
}
};
useEffect(() => {
console.log("setting Http Client with: ", workspaceId);
setHttpClient(logout, onError, workspaceId);
}, [workspaceId]);
};
Here is where i call the useHttpClient hook:
const DashboardPage = (): ReactElement => {
const dashboardData = useDashboardData();
const { userSettings } = useUserSettingsData();
const { period, onPeriodChanges, isLoading } = useDashboardPeriod();
const { t } = useTranslation();
const {
query: { workspaceId },
} = useRouter();
useHttpClientSetup();
useEffect(() => {
if (workspaceId) {
// Trigger data fetching or other actions based on workspaceId
console.log("Workspace ID changed:", workspaceId);
}
}, [workspaceId]);
const getBreadcrumbsPath = () =>
new BreadcrumbsPath(t("translation:dashboard"), generatePath({ pathname: AppRoutes.DASHBOARD, workspaceId }));
return (...rest of code)
The Issue:
The headers are getting configured correctly, but they are always one step late in the process. So when the app Id changes, the console -> console.log(“WORKSPACEID:”, workspaceId) is logging the correct values, but the next one inside the function body is always logging the previous one, and thus the config headers are always one step behind.
When the appId changes, the console logs the correct values for workspaceId and appId in the useEffect hook, but the values inside the interceptor function are always one step behind.
What I’ve Tried:
-
Ensured the interceptors are being correctly ejected and re-applied.
-
Logging to verify the values being passed to the interceptor setup function.
-
Read about using { synchronous: true }, but it seems to be no longer supported.
Philippe Ducasse is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
3