I have a vuex store, like following:
import spreeApi from '../../gateways/spree-api'
// initial state
const state = {
products: [],
categories: []
}
// mutations
const mutations = {
SET_PRODUCTS: (state, response) => {
state.products = response.data.products
commit('SET_CATEGORIES')
},
SET_CATEGORIES: (state) => {
state.categories = state.products.map(function(product) { return product.category})
}
}
const actions = {
FETCH_PRODUCTS: (state, filters) => {
return spreeApi.get('products').then(response => state.commit('SET_PRODUCTS', response))
}
}
export default {
state,
mutations,
actions
}
I want to call mutation: SET_CATEGORIES
from mutation: SET_PRODUCTS
, But this gives me error:
projectFilter.js:22 Uncaught (in promise) ReferenceError: commit is not defined(…)
What should be correct way to do this. I tried store.commit
and this.commit
, but these also gave similar errors.
To share code between mutations, you must create a new function that performs the work, which you can then reuse. Fortunately, mutations are just plain old functions, and we can pass the
state
parameter around however we like, so this is quite easy to do.For example:
This should fix it. You can inject the commit into your mutation from the action so you can commit from your mutation. Hope this helps
Reading the Vuex documentation on Actions, it's quite clear what they are made for.
Actions can (not must) contain asynchronous code. In fact, the following example is correct
I do not see any issue in using actions for performing multiple mutations.
In your case you should consider having only one mutation, namely SET_PRODUCTS.
You should never have any need to call SET_CATEGORIES separately. Think about it! Categories can only mutate if products are changed. And products can change only through SET_PRODUCTS.
Edit : I stumbled upon a very similar problem and the solution for me was to use a vuex getter : https://vuex.vuejs.org/en/getters.html
Your categories is actually a "computed" version of your products. Having categories as a getter allows you to keep them in sync with products and avoids duplicating the data in your store.
For the sake of answering the question in the title i leave my original answer.
An alternative to Daniel Buckmaster solution :
As you can see you could directly call the mutation itself. (as Daniel said, they are just plain functions after all)
I believe that this is a more appropriate answer to the original question : it is an actual way of composing mutations without code duplication or extra functions
For the record. To call other mutations from a mutation method do it like this: