Axios/Vue - Prevent axios.all() to keep executing

axios post json body
axios.post headers
axios cheat sheet
vue axios post
axios set header
axios tutorial
axios content-type
axios cancel multiple requests

In my application wile authenticating the user I call the fetchData function. If the user token become invalid, the application will run axios.all() and my interceptor will return a lot of errors.

How to prevent axios.all() of keep runing after the first error? And show only one notification to the user?

interceptors.js

export default (http, store, router) => {
    http.interceptors.response.use(response => response, (error) => {
        const {response} = error;

        let message = 'Ops. Algo de errado aconteceu...';

        if([401].indexOf(response.status) > -1){
            localforage.removeItem('token');

            router.push({
                name: 'login'
            });

            Vue.notify({
                group: 'panel',
                type: 'error',
                duration: 5000,
                text: response.data.message ? response.data.message : message
            });
        }

        return Promise.reject(error);
    })
}

auth.js

const actions = {
    fetchData({commit, dispatch}) {
        function getChannels() {
            return http.get('channels')
        }

        function getContacts() {
            return http.get('conversations')
        }

        function getEventActions() {
            return http.get('events/actions')
        }

        // 20 more functions calls

        axios.all([
            getChannels(),
            getContacts(),
            getEventActions()
        ]).then(axios.spread(function (channels, contacts, eventActions) {
            dispatch('channels/setChannels', channels.data, {root: true})
            dispatch('contacts/setContacts', contacts.data, {root: true})
            dispatch('events/setActions', eventActions.data, {root: true})
        }))
    }
}

EDIT: @tony19's answer is much better as it allows to cancel requests still pending after first error, and does not need any extra library.


One solution would be to assign a unique identifier (I will use the uuid/v4 package in this example, feel free to use something else) to all the requests you use at the same time:

import uuid from 'uuid/v4'

const actions = {
    fetchData({commit, dispatch}) {
        const config = {
            _uuid: uuid()
        }

        function getChannels() {
            return http.get('channels', config)
        }

        function getContacts() {
            return http.get('conversations', config)
        }

        function getEventActions() {
            return http.get('events/actions', config)
        }

        // 20 more functions calls

        axios.all([
            getChannels(),
            getContacts(),
            getEventActions()
        ]).then(axios.spread(function (channels, contacts, eventActions) {
            dispatch('channels/setChannels', channels.data, {root: true})
            dispatch('contacts/setContacts', contacts.data, {root: true})
            dispatch('events/setActions', eventActions.data, {root: true})
        }))
    }
}

Then, in your interceptor, you can choose to handle the error a single time using this unique identifier:

export default (http, store, router) => {
    // Here, you create a variable that memorize all the uuid that have
    // already been handled
    const handledErrors = {}
    http.interceptors.response.use(response => response, (error) => {
        // Here, you check if you have already handled the error
        if (error.config._uuid && handledErrors[error.config._uuid]) {
            return Promise.reject(error)
        }

        // If the request contains a uuid, you tell 
        // the handledErrors variable that you handled
        // this particular uuid
        if (error.config._uuid) {
            handledErrors[error.config._uuid] = true
        }

        // And then you continue on your normal behavior

        const {response} = error;

        let message = 'Ops. Algo de errado aconteceu...';

        if([401].indexOf(response.status) > -1){
            localforage.removeItem('token');

            router.push({
                name: 'login'
            });

            Vue.notify({
                group: 'panel',
                type: 'error',
                duration: 5000,
                text: response.data.message ? response.data.message : message
            });
        }

        return Promise.reject(error);
    })
}

Additional note, you could simplify your fetchData function to this:

const actions = {
    fetchData({commit, dispatch}) {
        const config = {
            _uuid: uuid()
        }

        const calls = [
            'channels',
            'conversations',
            'events/actions'
        ].map(call => http.get(call, config))

        // 20 more functions calls

        axios.all(calls).then(axios.spread(function (channels, contacts, eventActions) {
            dispatch('channels/setChannels', channels.data, {root: true})
            dispatch('contacts/setContacts', contacts.data, {root: true})
            dispatch('events/setActions', eventActions.data, {root: true})
        }))
    }
}

Axios/Vue - Prevent axios.all() to keep executing, If the user token become invalid, the application will run axios.all() and my interceptor will return a lot of errors. How to prevent axios.all() of keep runing after the� Teams. Q&A for Work. Stack Overflow for Teams is a private, secure spot for you and your coworkers to find and share information.

All You Need to Know About Axios, Like the Fetch API, Axios is a promise based HTTP client for making requests axios.all() accepts an array of Axios requests, and returns an array that component, React wouldn't know how to keep track of the posts and, hence to avoid any unexpected outcomes, we are calling the search() function in� Q&A for power users of Apple hardware and software. Stack Exchange network consists of 177 Q&A communities including Stack Overflow, the largest, most trusted online community for developers to learn, share their knowledge, and build their careers.

The upvoted answer proposes a solution that requires waiting for all responses to complete, a dependency on uuid, and some complexity in your interceptor. My solution avoids all that and addresses your goal of terminating Promise.all() execution.

Axios supports request cancelation, so you could wrap your GET requests with an error handler that cancels the other pending requests immediately:

fetchData({ dispatch }) {
  const source = axios.CancelToken.source();

  // wrapper for GET requests
  function get(url) {
    return axios.get(url, {
        cancelToken: source.token // watch token for cancellation
      }).catch(error => {
        if (axios.isCancel(error)) {
          console.warn(`canceled ${url}, error: ${error.message}`)
        } else {
          source.cancel(error.message) // mark cancellation for all token watchers
        }
      })
  }

  function getChannels() {
    return get('https://reqres.in/api/users?page=1&delay=30'); // delayed 30 secs
  }
  function getContacts() {
    return get('https://reqres.in/api/users?page=2'); // no delay
  }
  function getEventActions() {
    return get('https://httpbin.org/status/401'); // 401 - auth error
  }

  ...
}

In your interceptor, you'd also ignore errors from request cancellations:

export default (http, store, router) => {
  http.interceptors.response.use(
    response => response,
    error => {
      if (http.isCancel(error)) {
        return Promise.reject(error)
      }

      ...

      // show notification here
    }
}

demo

How to make HTTP requests like a pro with Axios, jQuery's $.ajax() function, for example, has been particularly popular with frontend developers. In this post we will take a good look at Axios, a client HTTP API .then(responseArr => { //this will be executed only when all requests are Keep in mind that if any of the arguments rejects then the promise will� Q&A for peer programmer code reviews. Stack Exchange network consists of 176 Q&A communities including Stack Overflow, the largest, most trusted online community for developers to learn, share their knowledge, and build their careers.

axios/axios, Interceptors - how to prevent intercepted messages from resolving as error #266 Authorization = 'Bearer ' + getAccessToken() axios(err.config) }, error a return statement from your interceptor which will keep the Promise alive. I am using Vue.js 2.0 my solution was to watch the token for changes in the� To execute multiple requests in parallel, simply provide an array argument to axios.all. When all requests are complete, you’ll receive an array containing the response objects in the same order they were sent. Alternatively you can use axios.spread to spread the array into multiple arguments. Spread is preferred since dealing with array

Can I do multiple requests in a row? � Issue #371 � axios/axios � GitHub, For instance: axios.get('http://www.google.com') .then(function (res) axios.all([ axios.get('http://google.com'), axios.get('http://apple.com') ]) I hadn't seen the axios.spread syntax before, so I figured I'd try to save some people a few minutes Is it possible to handle .catch() block for two requests separatelty. Learn how to create a Vue.js web application that asynchronously makes HTTP requests with Axios and uses Vuex as a central data store.

Axios Cheat Sheet, Make a request for a user with a given ID axios.get('/user? getUserPermissions () { return axios.get('/user/12345/permissions'); } axios.all([getUserAccount(),� axios#create([config]) axios#request(config) axios#get(url[, config]) axios#delete(url[, config]) axios#head(url[, config]) axios#options(url[, config])

Comments
  • See this answer at Wait until all ES6 promises complete, even rejected promises. You can alternatively substitute an AsyncGenerator and AsyncIterator for .all() see Run multiple recursive Promises and break when requested; see also Jquery Ajax prevent fail in a deferred sequential loop.
  • axio.all() uses Promise.all(). Can you demonstrate Promise.all() continuing execution after first exception or rejected Promise? Why is .catch() not chained to .then() to handle error?
  • axios.all doesn't execute anything, and it cannot "stop" anything. It just builds a promise that waits for other promises. You are calling getChannels(), getContacts() and getEventActions() immediately, they all are already running when you get the first error from them.
  • Your best bet will probably be to make one request that checks whether the user token is valid, and only when that succeeds run the others. Instead of relying on the interceptor.
  • Hi, I can see that you reopened a bounty on this question. How is my answer not responding to your question? Do you have other requirements that my answer does not fulfill?
  • This one is my favorite because it only uses Axios capabilities and because as you stated in here, the upvoted answer waits for all the promises to be completed. However I can't understand how the notification at first fail in the interceptor is supposed to be called. Is it?
  • @Hammerbot When the cancellation token is invoked, it throws an error for all other pending requests on that token, which causes the interceptor's error handler to be called.
  • Ho, ok I understand. The notification shows because the first error goes through the interceptor before first cancelation. This should definitely be the validated answer. I'm editing my answer to mention that.