Search code examples
vue.jsaxiosvuex

Catch Axios exception in Vuex store and throw it to Vue.js method


How to catch axios exceptions in vuex store and throw it to vue.js method ? My goal is to get this exception to be able to reset computed values bound to input using this.$forceUpdate().

In my method, I have this:

methods: {
    mymet: _.debounce(
        function(table, id, key, event) {
            const value = event.target.value;
            this.$store.dispatch('UPDATE_TRANSACTIONS_ITEM', { table, id, key, value }).then(response => {
                event.target.classList.remove("is-invalid")
                event.target.classList.add("is-valid")
            }, error => {
                console.error("Got nothing from server. Prompt user to check internet connection and try again")
                this.$forceUpdate();
            })
        }, 500
    )
}

In my vuex store, I have this:

const actions = {
    UPDATE_TRANSACTIONS_ITEM ({ commit }, data) {
        let company = {
            [data.key]: data.value
        }
        axios.put(`/api/companies/${data.id}`, { company }).then( function ( response ) {
            commit('SET_TRANSACTIONS_ITEM_UPDATE', { profile: data })
        }).catch(function (error) {
            throw error
        })
    }
}

const mutations = {
    SET_TRANSACTIONS_ITEM_UPDATE (state, { profile }) {
        state.company_data[profile.key] = profile.value
    },
}

Solution

  • You need to make the actual action function asynchronous.

    If you have the ability to use async functions, you can just await the axios call, and let the error bubble up (no need to throw anything in the action itself):

    const actions = {
      async UPDATE_TRANSACTIONS_ITEM ({ commit }, data) {
        let company = {[data.key]: data.value};
        await axios.put(`/api/companies/${data.id}`, { company }).then(() => {
          commit('SET_TRANSACTIONS_ITEM_UPDATE', { profile: data })
        });
      }
    }
    

    Otherwise, you'll need to return a Promise and catch the error and pass it to the reject handler:

    const actions = {
      UPDATE_TRANSACTIONS_ITEM ({ commit }, data) {
        return new Promise((resolve, reject) => {
          let company = {[data.key]: data.value};
          axios.put(`/api/companies/${data.id}`, { company }).then(() => {
            commit('SET_TRANSACTIONS_ITEM_UPDATE', { profile: data });
            resolve();
          }, (error) => reject(error));
        });
      }
    }