N
N
nastya_zholudeva2018-05-03 16:38:14
JavaScript
nastya_zholudeva, 2018-05-03 16:38:14

How to use axios to catch errors in one place and then redirect the user or show a modal depending on the error?

The task is this: I make requests with the help axiosof the server. With the help catchof love errors and if the API response is 401 Unauthorized, you need to redirect the user to the authorization page; when receiving a 403 Forbidden response from the API, the user needs to show a modal window with the inscription “Access denied”

Is there a way to catch them in one place?
I use axios, vue.js, vue-router. The display of any modal is made in such a way that modal = true date is passed to it and it is shown.

Now I have a separate config file configured for any request to the API

import axios from 'axios'
import api_config from '../../api_config'

function request(method, url, params, data) {
  let axios_config = {
    // `baseURL` is the server URL that will be used for the request
    baseURL: api_config.api_url,

    // `method` is the request method to be used when making the request
    method: method,

    // `url` will be prepended to `baseURL` unless `baseURL` is absolute.
    url: url,

    headers: {
      Authorization: 'Bearer ' + api_config.api_token
    }
  }

  if (params) {
    // `params` are the URL parameters to be sent with the request
    axios_config.params = params
  }

  if (data) {
    // `data` allows changes to the request data before it is sent to the server
    // This is only applicable for request methods 'PUT', 'POST', and 'PATCH'
    axios_config.data = data
  }

  // intercept responses before they are handled by then or catch
  axios.interceptors.response.use((response) => {
    console.log('response', response)
    return response
  }, (error) => {
    if (error.response.status == 401) {
      this.$router.push({ path: '/login' })
    }
    console.log('1111error', error.response.status)
    // return Promise.reject(error);
  })

  return axios(axios_config)
}

function get(url) {
  return request('get', url, null, null)
}

function post(url, data) {
  data = data || {}
  return request('post', url, null, data)
}

function put(url, data) {
  data = data || {}
  return request('put', url, null, data)
}

function remove(url) {
  return request('delete', url, null, null)
}

export default {get, post, put, remove, request}


I tried to redirect with axios.interceptors.response.useand this.$router.push({ path: '/login' })but I get an error
TypeError: Cannot read property '$router' of undefined
    at __WEBPACK_IMPORTED_MODULE_0_axios___default.a.interceptors.response.use
I think there is another way

Answer the question

In order to leave comments, you need to log in

1 answer(s)
M
Michael, 2018-05-03
@nastya_zholudeva

In principle, the approach is correct, I use it myself, though I haven’t come across the display of modals, I just have a redirect set up. You need to connect the router via import, since it will not be possible to reach it through this here.
In router.js file

const LoginView = () => import('@/views/Login');
const router = new Router({
  base: '/',
  mode: 'history',
  routes: [
    {
      path: '/login',
      name: 'login',
      component: LoginView,
    }
  ],
});
export default router;

In axios config file
import axios from 'axios';
import router from '../router';
const instance = axios.create({ baseURL });

instance.interceptors.response.use(undefined, (error) => {
  if (error.response && error.response.status === 401) {
    router.replace({
      path: '/login',
      query: { redirect: router.currentRoute.fullPath },
    });
  }
  return Promise.reject(error.response.data);
});

PS You can redirect with the necessary props and then you can show the modal if the required prop is set.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question