Search code examples
vue.jsaxiosvuex

Mutate vuex store state with action within axios response - commit does not work


Preamble

I'm completely stumped by this. The answer will be obvious, of that I am sure, but I can't see it.

The Problem:

I cannot write to my vuex store with an Axios response. I have read about and tried async/await, thought I had a decent grasp of promises and have copied examples word for word. No dice.

This is my mutator, it works when passed a payload outside of axios:

mutations: {
    setDays (state, payload) {
        state.savedDays = payload
    }
}

This action, created for debugging purposes, correctly updates the store with the word "cheese" and logs the expected response object to the console:

getDays ({commit}) {
    axios.get('/days/')
    .then( (response) => {
        console.log(response.data)
    })
    commit('setDays', "cheese")
}

This action does not update the store, but does still log correctly to the console:

getDays ({commit}) {
    return axios.get('/days/')
    .then( (response) => {
        // response object removed for debugging
        commit('setDays', "cheese")
        console.log(response.data)
    }
})

I have read the Vuex docs and many other solutions on here, have tried many things, including the following (doesn't work):

async getDays ({commit}) {
    const response = await axios.get('/days/')
    commit('setDays', response)
})

I receive no error messages, use chrome vue-devTools. Thank you in advance.


Okay, I did this to further test based on comments below:

async getDays ({commit}) {
    commit('setDays', "crackers")
    const response = await axios.get('/days/byType/30/1')
    console.log("Response:", response.data)
    commit('setDays', response.data)
    return response
}

When this action is dispatched, the store value is successfully mutated to "crackers".

console.log successfully logs the response object.

The second commit does nothing, even if I try and commit a string rather than the response.data object.


Solution

  • You were close with your third and fourth code sample. axios.get() returns a promise. so you either have to use async await or .then. To make your fourth example work, all you have to do is to commit response.data

    async getDays ({commit}) {
        const response = await axios.get('/days/')
        commit('setDays', response.data)
    })
    

    In order to return the value use the following lines

    async getDays ({commit}) {
        const response = await axios.get('/days/')
        commit('setDays', response.data)
        return response.data
    })
    

    FYI you could also use Object destructuring

    const { data } = await axios.get('/days/')
    commit('setDays', data)
    return data