hilongjw/vue-progressbar

Using start() and finish() on vuex axios call

sergiocastrovale opened this issue · 9 comments

Doing something like this won't work, since we don't have the context ("this") inside vuex:

login: ({ commit }, data) => {
    this.$Progress.start();

    axios.post('auth/login', params).then((response) => {
        if (response.status === 200) {
            this.$Progress.finish();
        }
    })
    .catch((error) => {
        console.log(error);
    });
},

As using vuex and axios is becoming more and more the de facto standard for medium and large applications, it would be a deal breaker if we couldn't do something like this. Is there any solution that doesn't involve "hacking it" by emitting events?

please?

Hey there - here's what I do in an app of mine - works great - although it's a different take on the same goal (from what I can see). Basically, instead of running the vue-progressbar manually on each request, I set the action up using axios interceptors - so it runs automatically. Works pretty seamlessly - even for errors - and hasn't caused any issues. Here's the repo and the live demo of the project. Note - I am using vue-router and grab the $Progress hook from there.

//The following two interceptor blocks are strickly for
//attaching the top-loading bar to all axios requests and
//stoping the bar on all responses.
axios.interceptors.request.use(function (config) {
    router.app.$Progress.start()
    return config;
}, function (error) {
    router.app.$Progress.fail()
    return Promise.reject(error);
});
axios.interceptors.response.use(function (response) {
    router.app.$Progress.finish()
    return response;
}, function (error) {
    router.app.$Progress.fail()
    return Promise.reject(error);
});

Hi @johndatserakis - thanks for this.

One question though: wouldn't this require two different bindings, one for axios requests and the other (possibly placed in App.vue) for regular component loading?

Yup - that's exactly right. In addition to the above code, my router file looks like this:

router.beforeEach((to, from, next) => {
    //Start our loading strip
    router.app.$Progress.start()
    next()
})

router.afterEach((to, from) => {
    //End our loading strip
    router.app.$Progress.finish()
})

And that's it - all components and api calls are handled without having to attach or detach anything.

Great - I had reached more or less the same conclusions as you did @johndatserakis but thanks for sharing the code snippets. I guess this will solve the issue for anyone that bumps into it.

@sergiocastrovale i not use router,how can i use $Progress.start() in axios

@busyhe If you import Vue, you can use $Progress like this:

Vue.prototype.$Progress.start()

@busyhe if you use vuex you can trigger a state mutation in the axios interceptor similar at what @johndatserakis is doing, then in your app.vue you can trigger the progress bar start or stop actions based on that vuex state

@sergiocastrovale thanks, 666