180

Consider a simple Vue blog:
I'm using Vuex as my datastore and I need to set up two getters: a getPost getter for retrieving a post by ID, as well as a listFeaturedPosts that returns the first few characters of each featured post. The datastore schema for the featured posts list references the posts by their IDs. These IDs need to be resolved to actual posts for the purposes of showing the excerpts.

store/state.js

export const state = {
  featuredPosts: [2, 0],
  posts: [
    'Lorem et ipsum dolor sit amet',
    'Lorem et ipsum dolor sit amet',
    'Lorem et ipsum dolor sit amet',
    'Lorem et ipsum dolor sit amet',
    'Lorem et ipsum dolor sit amet',
  ]
}

store/getters.js

export default getPost = (state) => (postID) => {
  return state.posts[postID]
}

export default listFeaturedPosts = (state, getters) => () => {
  console.log(getters) // {}

  return state.featuredPosts.map(postID => getters.getPost(postID).substring(0, EXCERPT_LENGTH);
}

store/index.js

import Vue from 'vue'
import Vuex from 'vuex'
import state from './state'
import * as getters from './getters'
import * as mutations from './mutations'

Vue.use(Vuex)

export default new Vuex.Store({
  state,
  getters,
  mutations
})

According to the documentation, the getters parameter can be used to access other getters. However, when I try to access getters from inside listFeaturedPosts, it's empty, and I get an error in the console due to getters.getPost being undefined in that context.

How do I call getPost as a Vuex getter from inside listFeaturedPosts in the example above?

Billal Begueradj
  • 20,717
  • 43
  • 112
  • 130
User not found
  • 2,129
  • 2
  • 15
  • 20

5 Answers5

291

In VueJS 2.0, you must pass both state and getters.

Getters are passed to other getters as the 2nd Argument:

export default foo = (state, getters) => {
    return getters.yourGetter
}

Official documentation: https://vuex.vuejs.org/guide/getters.html#property-style-access

whusterj
  • 3,359
  • 1
  • 17
  • 14
38

Pass getters as the second argument to access local and non-namespaced getters. For namespaced modules, you should use rootGetters (as the 4th argument, in order to access getters defined within another module):

export default foo = (state, getters, rootState, rootGetters) => {
    return getters.yourGetter === rootGetters['moduleName/getterName']
}
LJH
  • 7,444
  • 3
  • 10
  • 19
Be Kind
  • 4,712
  • 1
  • 38
  • 45
  • 4
    This is useful for people requiring a getter from another vuex module. I just wanted to emphasise that the arguments have to be in the specific order shown in the answer with no arguments omitted, in order for it to work. – LJH Jan 24 '19 at 19:22
28

Getters receive other getters as the 2nd argument

getters: {
  doneTodos: state => {
    return state.todos.filter(todo => todo.done)
  },
  doneTodosCount: (state, getters) => {
    return getters.doneTodos.length
  }
}

Here is a link to the official docs - https://vuex.vuejs.org/guide/getters.html#property-style-access

OziOcb
  • 387
  • 4
  • 6
  • 4
    Thumbs up for: a) a clear code example b) link to the proper place in docs – Katinka Hesselink Jun 27 '19 at 08:04
  • 1
    Is it differnce to write like this instead? getters: { doneTodos: state => { return state.todos.filter(todo => todo.done) }, doneTodosCount: (state, getters) => { return this.getters.doneTodos.length } } – Rivo Oct 09 '19 at 22:17
  • @Rivo as far as I know you can't do that. If you try you'll get an error like this: [Vue warn]: Error in render: "TypeError: Cannot read property 'getters' of undefined" – OziOcb Oct 11 '19 at 08:44
22

I Tested without state and didn't work. That's why state is necessary.

this works:

export default foo = (state, getters) => {
    return getters.yourGetter
}

this didn't work

export default foo = (getters) => {
    return getters.yourGetter
}
Jose Seie
  • 892
  • 11
  • 12
  • 1
    I'd like to add that it doesn't work in any Vue version. Object destructuring should not be confused with named arguments (see answer in original suggestion to omit 'state'). It is indeed (state, getters) – Igor Zinken Dec 21 '18 at 12:43
  • 3
    In the second example you are naming the `state` object `getters` and ignoring the second argument which would be the actual `getters` object. If you were to introspect `getters` in this example, you would see it was actually your state object. – mraaroncruz Feb 13 '20 at 15:19
-6

instead of passing state, pass getters and then call any other getter you want. Hope it helps.

In your store/getters.js

export default foo = (getters) => {
   return  getters.anyGetterYouWant
}
Angie
  • 140
  • 1
  • 8
  • 3
    I think you're confusing Object destructuring with arguments. The first argument to the function is the state, the second is the getters Object. You can name the first argument 'getters', but it will still be the state! You're looking for: export default foo = (state, getters) => ... – Igor Zinken Dec 21 '18 at 12:42
  • Or `export default foo = ({ getters }) => { return getters.anyGetterYouWant }` – GaryMcM May 07 '19 at 15:29