Skip to content

Uncaught TypeError: Cannot read property 'getters' of undefined #264

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
brainyl opened this issue Aug 1, 2016 · 28 comments
Closed

Uncaught TypeError: Cannot read property 'getters' of undefined #264

brainyl opened this issue Aug 1, 2016 · 28 comments

Comments

@brainyl
Copy link

brainyl commented Aug 1, 2016

This error is thrown when you use any of the vuex helpers in a child component. From debugging, I noticed the store is not being injected into child components. For example, when I have this code in a child component, the error is thrown

computed: {
   ...mapGetters({
    notifications: 'notification.all'
  })
}

I suspect there is breaking change with the current version of vuex and vue.

@ktsn
Copy link
Member

ktsn commented Aug 1, 2016

I looked into it and the vuex store is injected into a child component certainly.
https://jsfiddle.net/0qmjcwmw/1/

It looks like you define the all getter in the notification module, but you should only give the getter name to mapGetters.

computed: {
  ...mapGetters({
    notifications: 'all'
  }) 
}

Because all getters functions you defined on the store are gathered and flattened to store.getters object.

@brainyl
Copy link
Author

brainyl commented Aug 1, 2016

@ktsn Thank you. The problem is not from my code, the sample above is a working code from a Vue 1.0 App. 'notifaction.all' is how I write my getters in a module, prefixing my methods with the module name. The issue is trying to call $store on a child component which throws that error:

 res[key] = function mappedGetter() {
        if (!(val in this.$store.getters)) {
          console.error("[vuex] unknown getter: " + val);
        }
        return this.$store.getters[val];
      };

The same applies to mapState, mapActions etc. I tested your sample and even used Vue 2 and it works just fine. Maybe the problem is from my build tool (vue-loader). Just cannot get my head around it.

@ktsn
Copy link
Member

ktsn commented Aug 1, 2016

Hmm, I am still not sure why it is happened...
Can you share your Vue and Vuex version, the code of your root component and Vuex store, and also build configuration?
I'll look into it deeper.

@brainyl
Copy link
Author

brainyl commented Aug 1, 2016

Okay, thank you. I have created a gist for it, you can find it here https://gist.github.com/brainyl/e43dbe74916fc071dc99c1eff3f90274

@ktsn
Copy link
Member

ktsn commented Aug 1, 2016

Thank you! I find the problem on my environment too.
I'll try to fix and let you know about the solution later :)

@brainyl
Copy link
Author

brainyl commented Aug 1, 2016

Okay @ktsn. Thank you!

@ktsn
Copy link
Member

ktsn commented Aug 2, 2016

@brainyl
I realize the solution of this issue. Please try the following steps.

  1. Add alias of vue in webpack.config

    module.exports = {
      // ...
      resolve: {
        alias: {
          vue: 'vue/dist/vue.js'
        }
      },
      // ..
    }
  2. Rewrite all import Vue from 'vue/dist/vue.js' to import Vue from 'vue'

  3. Then it should work

The problem is caused by duplicated loading of vue.js.
Your code only loads the standalone build of vue.js (import Vue from vue/dist/vue.js) but vue-loader will load the runtime only build for hot reloading internally (require('vue') i.e. vue/dist/vue.common.js).
So, you can solve this problem by adding alias to standalone build.

@brainyl
Copy link
Author

brainyl commented Aug 2, 2016

Thank you @ktsn. It is now working as expected. The Vue ecosystem is simply awesome!

@brainyl brainyl closed this as completed Aug 2, 2016
@LinusBorg
Copy link
Member

@ktsn @yyx990803 Do you guys think this can be avoided somehow, or is this something we should warn users about when explaining the differences about the different builds?

If the latter, it should probably be explained in the vue-loader doc as well as the webpack-specific template docs, right?

@ktsn
Copy link
Member

ktsn commented Aug 3, 2016

@LinusBorg @yyx990803
I guess it could be avoided by providing the runtime template compiler as a plugin instead of standalone build. But it might increase entire file size because both file might have shared util code.

import Vue from 'vue' // runtime-only build
import compiler from 'vue-runtime-compiler' // load template compiler

Vue.use(compiler) // enable compiler

In any way, I think it should be explained on vue-loader (and vueify) doc because it is hard to solve if users face this problem.

@LinusBorg
Copy link
Member

Agreed.

@yyx990803
Copy link
Member

@ktsn @LinusBorg indeed, this probably should be noted on the installation page as well - basically, if using a module bundler, never do import Vue from 'vue/dist/vue', but rather use the alias option in the bundler. /cc @chrisvfritz

@webnoob
Copy link

webnoob commented Jan 11, 2017

I am also experiencing this issue but am not using the build version of vue. In my code, I do import Vue from 'vue' and have the mapGetter in a globally included mixin. Is that supported?

EDIT: Worth noting, my mapGetters is like so:

computed: {
    ...mapGetters({
      user: 'getUser'
    })
  }

It works fine when I call this.user from within a method (so any function between the methods: {} but not when calling within the mixin's created or mounted event.

@jartaud
Copy link

jartaud commented Apr 17, 2017

Same as @webnoob comment

@connor11528
Copy link

I also encountered this error and it was because I forgot to put store in my main Vue bootup (main.js) file like so:

new Vue({
  el: '#app',
  render: h => h(App),
  router,
  store
})

@node-monk
Copy link

@connor11528 THANK YOU!! After about 1hr of trying to figure out why mapGetters was not working, I came across your comment and checked my main.vue -- hand slap my own head :P

@webnoob
Copy link

webnoob commented Sep 21, 2017

@connor11528 I was also missing the Store in my bootup. Think it went missing when I was refactoring, whoops.

@shanemgrey
Copy link

I was thrown off by the fact that all my getters worked individually, but when I tried to use mapGetters, this is the error it failed with.

I didn't have store in my new Vue({...}) as others have noted. But I'm not sure I ever would have found that problem without this old, obscure, and closed issue. The error offers no clear indication that this might be the cause.

I think there should be a note in the docs somewhere indicating either that store should always be in new Vue({...}) when vuex is in use, or that it needs to be there if using the helpers.

@Prior99
Copy link

Prior99 commented Jun 28, 2018

Just if anybody ever encounters this issue while using Vuex in Jest:

  "moduleNameMapper": {
    "vue$": "<rootDir>/node_modules/vue/dist/vue.js"
  },

solved a similar issue for me.

@Prior99
Copy link

Prior99 commented Jul 2, 2018

It looks like this is related to the template compiler of either vue-jest or vue test utils. When adding this mapper as described in my comment above this issue is solved, but child components are not mounted correctly anymore.

@irina9215
Copy link

irina9215 commented Jul 4, 2018

@Prior99 It happened to me, the similar issue. The map module issue was gone by changing the moduleNameMapper in jest config, then vue test utils fail to mount template or render. I am still working on how to fix it.

@Prior99
Copy link

Prior99 commented Jul 5, 2018

@irina9215 Are you using createLocalVue? For me removing that and using the default Vue fixed that (And not using the moduleNameMapper). See this issue in vue test utils.

@haryzxw
Copy link

haryzxw commented Sep 13, 2018

@connor11528 THANK YOU! I forgot too

@Austio
Copy link
Contributor

Austio commented Oct 10, 2018

I also ran into this when running in a non-compiled environment. I setup this code sandbox to prove it worked. https://codesandbox.io/s/8knp1jm918

My Errors was that i was importing use import Vue from 'vue/dist/vue.esm.browser'; in my main file but when i was using that in my vuex file i was doing import Vue from 'vue'; After switching usage in vuex store file it worked

@DharunManivel
Copy link

TypeError: Cannot read property 'getters' of undefined
at VueComponent.visitLists (pages_visits_index.js:55)
at Watcher.get (commons.app.js:15219)
at Watcher.evaluate (commons.app.js:15324)
at VueComponent.computedGetter [as visitLists] (commons.app.js:15574)
at Object.get (commons.app.js:12851)
at Proxy.render (pages_visits_index.js:143)
at VueComponent.Vue._render (commons.app.js:14310)
at VueComponent.updateComponent (commons.app.js:14805)
at Watcher.get (commons.app.js:15219)
at new Watcher (commons.app.js:15208)

@lwisne
Copy link

lwisne commented Mar 18, 2019

Have this issue as well. Trying to run a trivial test with jest and getting a horrible looking stack trace. :(

TypeError: Cannot read property 'getters' of undefined at VueComponent.mappedGetter (node_modules/vuex/dist/vuex.common.js:887:73) at Watcher.get (node_modules/vue/dist/vue.runtime.common.dev.js:4442:25) at Watcher.evaluate (node_modules/vue/dist/vue.runtime.common.dev.js:4547:21) at Proxy.computedGetter (node_modules/vue/dist/vue.runtime.common.dev.js:4796:17) at Proxy.render (src/components/TodoList.vue:42:537) at VueComponent.Vue._render (node_modules/vue/dist/vue.runtime.common.dev.js:3532:22) at VueComponent.updateComponent (node_modules/vue/dist/vue.runtime.common.dev.js:4036:21) at Watcher.get (node_modules/vue/dist/vue.runtime.common.dev.js:4442:25) at new Watcher (node_modules/vue/dist/vue.runtime.common.dev.js:4431:12) at mountComponent (node_modules/vue/dist/vue.runtime.common.dev.js:4043:3) at VueComponent.Object.<anonymous>.Vue.$mount (node_modules/vue/dist/vue.runtime.common.dev.js:8368:10) at init (node_modules/vue/dist/vue.runtime.common.dev.js:3112:13) at createComponent (node_modules/vue/dist/vue.runtime.common.dev.js:5935:9) at createElm (node_modules/vue/dist/vue.runtime.common.dev.js:5882:9) at createChildren (node_modules/vue/dist/vue.runtime.common.dev.js:6010:9) at createElm (node_modules/vue/dist/vue.runtime.common.dev.js:5911:9) at createChildren (node_modules/vue/dist/vue.runtime.common.dev.js:6010:9) at createElm (node_modules/vue/dist/vue.runtime.common.dev.js:5911:9) at createChildren (node_modules/vue/dist/vue.runtime.common.dev.js:6010:9) at createElm (node_modules/vue/dist/vue.runtime.common.dev.js:5911:9) at VueComponent.patch [as __patch__] (node_modules/vue/dist/vue.runtime.common.dev.js:6432:7) at VueComponent.Vue._update (node_modules/vue/dist/vue.runtime.common.dev.js:3915:19) at VueComponent.updateComponent (node_modules/vue/dist/vue.runtime.common.dev.js:4036:10) at Watcher.get (node_modules/vue/dist/vue.runtime.common.dev.js:4442:25) at new Watcher (node_modules/vue/dist/vue.runtime.common.dev.js:4431:12) at mountComponent (node_modules/vue/dist/vue.runtime.common.dev.js:4043:3) at VueComponent.Object.<anonymous>.Vue.$mount (node_modules/vue/dist/vue.runtime.common.dev.js:8368:10) at Object.<anonymous> (test/unit/specs/TodoMVC.spec.js:8:32) at Object.asyncFn (node_modules/jest-jasmine2/build/jasmine_async.js:82:37) at resolve (node_modules/jest-jasmine2/build/queue_runner.js:52:12) at new Promise (<anonymous>) at mapper (node_modules/jest-jasmine2/build/queue_runner.js:39:19) at promise.then (node_modules/jest-jasmine2/build/queue_runner.js:73:82) at process._tickCallback (internal/process/next_tick.js:68:7)

@sethidden
Copy link

This happened to me because of a circular import.

myfile.ts imported a store instance, but somewhere deep one of the store's submodules imported myfile.ts

Commenting out the line where myfile.ts imports the store fixed the issue

@bilal-rizwaan
Copy link

"TypeError: Cannot read property 'getters' of undefined"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests