Vuex mapstate object undefined and "[vuex] unknown mutation type: "
Asked Answered
D

5

5

I'm new with vue.js and vuex and I've an issue with the mapstate object, first I've only one module in my store:

-Store
 -index.js
 -mutations.js
 -actions.js
 -state.js

state.js :

export default {
    userInfo: {
        messages: [{ 1: 'test', 2: 'test' }],
        notifications: [],
        tasks: []
    }
}

So when I try to access the userInfo object everything works correctly:

computed: {
    ...mapState(["userInfo"]),
}

Then I decided to create modules:

-Store
 -modules
  -ldap.js
 -commons.js
 -index.js

So the userInfo is in the commons.js file and now when I try to get the object I always get undefined:

commons.js

// state
const state = {
    userInfo: {
        messages: [{ 1: 'test', 2: 'test' }],
        notifications: [],
        tasks: []
    }
}

export default {
    actions,
    mutations,
    state  
}

Component.vue

computed: {
    ...mapState(["userInfo"]), // <---- undefined
}

main.js :

import Vue from 'vue'
import Vuex from 'vuex'
import commons from './commons'
import ldap from './modules/ldap'

Vue.use(Vuex)

export default new Vuex.Store({
    modules : {
        commons,
        ldap
    } 
})

Can you tell me how to access the userInfo object?

Thanks.

Detest answered 9/3, 2018 at 11:40 Comment(3)
How did you setup your module? Actually I don't see any evidence that you're using vuex-modules?Unamerican
Did you namespace your module....i.e setnamespaced: true in your module?Kaiser
No I dont, I will try to set the namespaced, thank youDetest
A
12

Considering:

  • Your commons.js is as follows:

    // state
    const state = {
        userInfo: {
            messages: [{ 1: 'test', 2: 'test' }],
            notifications: [],
            tasks: []
        }
    }
    
    export default {
        namespaced: true, // <== make sure this is defined
        actions,
        mutations,
        state  
    }
    
  • And main.js imports it like:

    import commons from './commons'
    // ..
    export default new Vuex.Store({
        modules : {
            commons,
            ldap
        } 
    })
    
  • Then update on Component.vue:

    import { mapState } from 'vuex'
    
    // ...
    
    computed: {
        ...mapState('commons', ["userInfo"]), // <== add module name here
    }
    

    Or

    import { createNamespacedHelpers } from 'vuex'
    
    const { mapState, mapActions } = createNamespacedHelpers('commons')
    
    // ...                          notice module name above ^^^^^^^^^
    
    computed: {
        ...mapState(["userInfo"]),
    }
    

"[vuex] unknown mutation type: "

Since you are now namespacing your commons module, that modules' mutations now must be prefixed.

So, say you had a mutation like:

const mutations = {
    changeName(state, data) {
        state.name = data;
    }
}
export default {
    namespaced: true, 
    actions,
    mutations,
    state  
}

And you used it like:

this.$store.commit('changeName', "New Name");

Now use it like:

this.$store.commit('commons/changeName', "New Name");
Actiniform answered 9/3, 2018 at 12:31 Comment(2)
Yes I did that but do you know why my mutations stop working?? "[vuex] unknown mutation type: "Detest
Thank you so much!Detest
R
1

You have to define each module as a individual store, here some pseudo example.

// authStore.js

import mutations from './authMutations'
import actions from './authActions'
import getters from './authGetters'

const initialState = {
  ...
}

export default {
  state: initialState,
  mutations,
  actions,
  getters
}

Then, register the modules

import authStore from './authStore'

const store = new Vuex.Store({
  modules: {
   {...authStore, namespaced: true},
   {...postStore, namespaced: true} // some other module defined like auth
  }
})

new Vue({
  ....
  store: store
})

And then, on the component use it:

import { createNamespacedHelpers } from 'vuex'

// map state and actions of the module
const { mapState, mapActions } = createNamespacedHelpers('auth')

export default {
  computed: {
     ...mapState({
       prop1: 'prop1'
     })
  }
}

Vuex modules docs

Riha answered 9/3, 2018 at 12:0 Comment(0)
K
1

I guess you have namspaced your modules by adding namespaced: true in your module.

So you should pass the module name as the first argument to the mapState helpers so that all bindings are done using that module as the context. See Binding Helpers with Namespace

computed: { 
    ...mapState('commons' , ["userInfo"])
}
Kaiser answered 9/3, 2018 at 12:7 Comment(0)
G
1

It is really unclear in the documentation but namespaced: true is required to use the map functions.

At least as of the last comment in this discussion https://github.com/vuejs/vuex/issues/855

Giule answered 28/6, 2018 at 19:27 Comment(0)
S
0

Without the need to namespace your modules you can use the callback variant of mapstate:

computed: {
    ...mapState({
        userInfo: state => state.commons.userInfo,
    }),
},
Scrivens answered 15/9, 2018 at 9:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.