Reputation: 92725
I have two modules in my vuex store.
var store = new Vuex.Store({
modules: {
loading: loading
posts: posts
}
});
In the module loading
, I have a property saving
which can be set either true
or false
and also have a mutation function named TOGGLE_SAVING
to set this property.
In the module posts
, before and after fetching posts, I want to change the property saving
. I am doing it by calling commit('TOGGLE_SAVING')
from one of the actions in the posts
module.
var getPosts = function (context) {
context.commit(TOGGLE_LOADING);
};
When it tried to commit, I got following error in the console
[vuex] unknown local mutation type: TOGGLE_LOADING, global type: posts/TOGGLE_LOADING
How can I mutate state in another module using commit
?
Upvotes: 119
Views: 70590
Reputation: 235
Using: Named modules, I had the same problem:
unknown mutation type
I have a common module : commonModule.js
import store from '../../';
const SET_ERROR = 'SET_ERROR'
export default {
state: () => ({
error: [],
}),
mutations: {
[SET_ERROR] (state, payload){
state.error = payload
},
},
actions: {
setError ({ commit }, error) {
commit(SET_ERROR, error)
},
},
}
Then in all other modules I had to call set error, so I called like this, which is error:
commit('setError', 'Socket is not defined!')
later I changed to this, which in my case solved the problem:
commit('SET_ERROR', 'Socket is not defined!')
I later deleted:
namespace: true,
This form is not working:
commit('commonModule/SET_ERROR', 'Socket is not defined!')
nor this one:
commit('commonModule/setError', 'Socket is not defined!')
hope to be useful.
Upvotes: 0
Reputation: 513
If you have used namespaced: true
in your modules, there are two ways for it:
1- you should add { root: true }
:
commit('TOGGLE_LOADING', null, { root: true })
2- define a global action as below (e.g. globalToggleLoading) and call it from any modules you want by dispatch('globalToggleLoading')
globalToggleLoading: {
root: true,
handler({ commit }) {
commit('TOGGLE_LOADING')
}
}
If your modules are not namespaced
, you can call any mutations or actions by calling commit, dispatch:
commit('TOGGLE_LOADING')
Upvotes: 3
Reputation: 10348
You can also import the store, as you normally do in any js file and use it. For example:
// src/state/modules/posts.js
import store from '@/state/store'
...
store.commit('posts/TOGGLE_LOADING')
...
This works pretty well, the only donwside is that can difficult isolate tests or mock-up.
Edition: Recently I have eliminated all code using the technique I mention due the testing problems. Indeed you can always change the state of other modules following the recommended way, as in this example. Very useful if you manage auth and profile in distincts modules.
logout: context => {
return new Promise((resolve) => {
// Clear token in all axios requests
axios.defaults.headers.common['Authorization'] = ''
// Logout from firebase
firebase
.auth()
.signOut()
.then(() => {
// Update state in profile module
context.commit('profile/SET_USER', null, {
root: true
})
resolve()
})
.catch(error => reject(error))
})
}
Upvotes: 2