Search code examples
javascriptvue.jsvuexvuex-modules

Can't access Vuex Module Getter - Cannot read property 'getters' of undefined"


I can't access a stores getter for some reason.

File structure: /store/index.js /store/modules/auth.js

store/index.js

import Vuex from 'vuex';
import Vue from 'vue';
import auth from './modules/auth';

Vue.use(Vuex);

export default new Vuex.Store({
  modules: {
    auth
  }
});

auth.js

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex);

export default new Vuex.Store({
    state: {
        token: '',
        status: ''
    },

    mutations: {},

    actions: {
        [AUTH_REQUEST]: ({ commit }, {username, password}) => {
            return new Promise((resolve, reject) => {
                commit(AUTH_REQUEST)
                axios({ url: 'authenticate', data: {username, password}, method: 'POST' })
                    .then(resp => {
                        const token = resp.data.token
                        commit(AUTH_SUCCESS, token)
                        resolve(resp) // router.push in login vue
                    })
                    .catch(err => {
                        commit(AUTH_ERROR, err)
                        reject(err)
                    })
            })
        }
    },

    getters: {
        isAuthenticated: state => !!state.token,
        authStatus: state => state.status
    }
})

App.vue

...
<v-app-bar-nav-icon @click="drawer = !drawer"  v-if="this.authenitcated">
...
computed: {
    ...mapGetters({authenitcated: 'isAuthenticated'})
}

I've tried a few variations, including namespaced getters, but have yet to find why it doesn't work. Following this tutorials code, everything looks identical except how the store is implemented. The tutorial uses slightly different JS. https://www.youtube.com/watch?v=5lVQgZzLMHc&t=2686s

Stack trace

TypeError: Cannot read property 'getters' of undefined
    at VueComponent.mappedGetter (webpack-internal:///./node_modules/vuex/dist/vuex.esm.js:930)
    at Watcher.get (webpack-internal:///./node_modules/vue/dist/vue.runtime.esm.js:4473)
    at Watcher.evaluate (webpack-internal:///./node_modules/vue/dist/vue.runtime.esm.js:4578)
    at VueComponent.computedGetter [as authenitcated] (webpack-internal:///./node_modules/vue/dist/vue.runtime.esm.js:4828)
    at Object.get (webpack-internal:///./node_modules/vue/dist/vue.runtime.esm.js:2071)
    at Proxy.render (eval at ./node_modules/cache-loader/dist/cjs.js?{"cacheDirectory":"node_modules/.cache/vue-loader","cacheIdentifier":"64b49ba3-vue-loader-template"}!./node_modules/vue-loader/lib/loaders/templateLoader.js?!./node_modules/vuetify-loader/lib/loader.js?!./node_modules/cache-loader/dist/cjs.js?!./node_modules/vue-loader/lib/index.js?!./src/App.vue?vue&type=template&id=7ba5bd90& (app.js:1031), <anonymous>:16:16)
    at VueComponent.Vue._render (webpack-internal:///./node_modules/vue/dist/vue.runtime.esm.js:3542)
    at VueComponent.updateComponent (webpack-internal:///./node_modules/vue/dist/vue.runtime.esm.js:4060)
    at Watcher.get (webpack-internal:///./node_modules/vue/dist/vue.runtime.esm.js:4473)
    at new Watcher (webpack-internal:///./node_modules/vue/dist/vue.runtime.esm.js:4462)

Thanks


Solution

  • Few things:

    If you export the store like you do in auth.js, you probably have to import it like this:

    import * as auth from './auth';
    

    I think it makes a namespace automatically here for your Auth-Store, so normally you would access it like this:

    ...mapGetters({
      whatever: 'auth/isAuthenticated',
    }),
    

    But if you have no other store with a isAuthenticated getter it should be fine. Why even bother to reassign it to the 'fake-name' authenitcated in your App.vue. You could simply:

    ...mapGetters([
      'auth/isAuthenticated',
      // ...
    ])
    

    And access it via this.isAuthenticated.