In my Vue app, I have a response interceptor:
axios.interceptors.response.use(function (config) {
return config;
}, error => {
if (error.response.status !== 401) {
return new Promise((resolve, reject) => {
reject(error);
});
}
if (error.response.status === 401 && error.response.data.message === 'Token Expired') {
this.store.dispatch('auth/refreshToken').then(aToken => {
var config = error.config;
axios.defaults.headers.common['Authorization'] = 'Bearer ' + aToken;
return new Promise((resolve, reject) => {
axios.request(config).then(response => {
console.log(response);
resolve(response);
}).catch((error) => {
reject(error);
});
});
});
}
});
...where I am refreshing the token and making the last (intercepted) request again with the new token.
But the problem is, say I have a component, Product.vue
, where I am making a request to the /products
endpoint when the component mounts. I am storing all the products in a products
data variable of that component. Imagine the user is in the /dashboard
route now. He went for a sip of coffee and by the time he comes back the token is already expired. He visits the /products
route, the response is 401, so the interceptor intercepts that response, updates the token, and then attempts to make the last failed request with the new token.
But this new request was not performed from the Product
component. It was performed from the interceptor, where I don't have access to the Product
component. Hence, although the request was successful, my response data are lost and the end-user will see nothing in the view because the products
variable is empty.
Is there a way to track which component performed the request and remount it in the interceptor? I tried $router.push('/products')
but vue throws an exception stating that navigation to current route not allowed.
Or, is there some way to handle the promise that is being returned from the interceptor in the Product component?