Vuex reactive mapGetters with arguments passed through
Asked Answered
D

1

6

I have lots of getters that pass arguments to the store such as:

this.$store.getters['getSomeThing'](this.id)

And I'm not finding recommendations for how to optimally use mapGetters to maintain reactivity, while passing the arguments through. One suggestion I found was to map the getter and then pass the argument in mounted:

computed: {  
  ...mapGetters([
    'getSomeThing'
  ])
},
mounted () {
  this.getSomeThing(this.id)
}

This really seems to be sub-optimal, as it would only check for a change to state on mounted. Any suggestions for how to best maintain reactivity while passing an argument to a getter? Here's an example of a getter that would match the above code:

getSomeThing: (state) => (id) => {
  return state.things.find(t => { return t.id === id })
}
Distributee answered 9/1, 2019 at 18:41 Comment(5)
If the data returned from getSomeThing does not change, my best guess is that you did not set this.id in your data function, causing it to be not reactive. The mapper will return the getSomeThing version, which is static. You do not want/have to return a different function somehow. You want the function to be called again when this.id is changed, which apparently does not happen.Dateless
A sandbox showcasing that: codesandbox.io/s/kxz40j7z53Dateless
Do you have any code examples? Do you mean if the object that this.id is attached changes at all? In this example, this.id would never change, but the rest of the object will.Distributee
Show the code that uses data returned from this getter.Tericaterina
Alternatively if you do not change this.id, but instead change the state, you may be doing something that does not properly update the state (e.g. object manipulation without the vue helper functions). I have added something to the example that shows reactivity working just fine if we do not change the argument of the function but instead change the state.Dateless
C
20

Here is a snippet from a project I have:

    computed: {
        ...mapGetters('crm', ['accountWithId']),
        account() {
            return this.accountWithId(this.$route.params.id)
        }
    },

This makes this.account reactive and dependent on the param.

So...

computed: {  
  ...mapGetters([
    'getSomeThing'
  ]),
  thing() {
    return this.getSomeThing(this.id)
  }
},
Cantilena answered 9/1, 2019 at 19:4 Comment(1)
For anyone looking this is the solution. I don't know why, but for some reason: 'crm', ['accountWithId'] works and 'crm/accountWithId' doesn'tHamza

© 2022 - 2024 — McMap. All rights reserved.