Axios interceptors and asynchronous login
Just use another promise :D
axios.interceptors.response.use(undefined, function (err) { return new Promise(function (resolve, reject) { if (err.status === 401 && err.config && !err.config.__isRetryRequest) { serviceRefreshLogin( getRefreshToken(), success => { setTokens(success.access_token, success.refresh_token) err.config.__isRetryRequest = true err.config.headers.Authorization = 'Bearer ' + getAccessToken(); axios(err.config).then(resolve, reject); }, error => { console.log('Refresh login error: ', error); reject(error); } ); } throw err; });});
If your enviroment doesn't suport promises use polyfill, for example https://github.com/stefanpenner/es6-promise
But, it may be better to rewrite getRefreshToken to return promise and then make code simpler
axios.interceptors.response.use(undefined, function (err) { if (err.status === 401 && err.config && !err.config.__isRetryRequest) { return getRefreshToken() .then(function (success) { setTokens(success.access_token, success.refresh_token) ; err.config.__isRetryRequest = true; err.config.headers.Authorization = 'Bearer ' + getAccessToken(); return axios(err.config); }) .catch(function (error) { console.log('Refresh login error: ', error); throw error; }); } throw err;});
Could do it in the request instead of the response, and it'd probably be cleaner since it'd avoid hitting the server when the access token's expired. Copying from this article:
function issueToken() { return new Promise((resolve, reject) => { return client({ ... }).then((response) => { resolve(response); }).catch((err) => { reject(err); }); });}client.interceptors.request.use((config) => { let originalRequest = config; if (tokenIsExpired && path_is_not_login) { return issueToken().then((token) => { originalRequest['Authorization'] = 'Bearer ' + token; return Promise.resolve(originalRequest); }); } return config;}, (err) => { return Promise.reject(err);});