diff --git a/src/boot/axios.js b/src/boot/axios.js index 4736942..fe453a5 100644 --- a/src/boot/axios.js +++ b/src/boot/axios.js @@ -13,8 +13,24 @@ const api = axios.create({ }, }) +// SSR: boot() runs again for every request, but `api` above is a +// module-level singleton created once. Without ejecting the previous +// request's interceptors before adding new ones, api.interceptors.* +// would grow without bound for the lifetime of the process, each +// handler closing over that request's (by-then-stale) store - see +// handoffs/01-axios-interceptors-leak.md for the full analysis. +let requestInterceptorId +let responseInterceptorId + export default boot(({store}) => { - api.interceptors.request.use((config) => { + if (requestInterceptorId !== undefined) { + api.interceptors.request.eject(requestInterceptorId) + } + if (responseInterceptorId !== undefined) { + api.interceptors.response.eject(responseInterceptorId) + } + + requestInterceptorId = api.interceptors.request.use((config) => { const token = useAuthStore(store).getAccessToken(); if (token) { config.headers['Authorization'] = `Bearer ${token}` @@ -28,7 +44,7 @@ export default boot(({store}) => { }) // Response interceptor for API calls - api.interceptors.response.use( + responseInterceptorId = api.interceptors.response.use( (response) => response, async function (error) { const originalRequest = error.config; diff --git a/src/composables/pagination.js b/src/composables/pagination.js index 292abba..7c31bb5 100644 --- a/src/composables/pagination.js +++ b/src/composables/pagination.js @@ -10,9 +10,9 @@ export const usePagination = ({fetchFunction, itemsPerPage = 10}) => { const paginationOffset = ref(0); const filters = ref({}); const hasMoreData = ref(true) - const isQueryRunning = ref(false) + const loadFirstPage = () => { paginationOffset.value = 0 isQueryRunning.value = true