Vue dynamic mapGetters
Asked Answered
S

3

11

I have a props that i want to use to make a dynamic mapGetters but the the mapGetters sees the props as undefined, probably because the computed is loaded before the props. Do anybody know how i can make it dynamic? my code is as follow:

export default {
    props: ['listType'],
    components: {
        addrow: AddRow
    },
    computed: {
        ...mapGetters({
            list: `${this.listType}/list`,
            current: 'Dropdown/current'
        }) 
    },
}
Shortage answered 30/9, 2018 at 12:31 Comment(9)
try it without this keyword like list: `${listType}/listRetrospection
I tried that but then im getting an error: listType is not definedShortage
did you try list:this.listType+'/list'Retrospection
could you show how to call the component in the parent one?Retrospection
Thanks for u reply, When i try list:this.listType+'/list' then its still undefined, When i console.log the listType on mounted it works fine, its undefined because the computed is loaded before props and everything, Im just curious if there is a vue function or something to archive this.Shortage
i usually call props in my computed property without any problem, so the problem is with ...mapGetters , i believe if you try computed:{getList(){return this.listType}} it should workRetrospection
please please provide your store objectRetrospection
Thanks alot, i just tested the getList() that u provided and i see that that the prop is working on a computed so the namspace of the mapGetters is just not correct. i did some research and i found the solution, Thanks alot for your your help you really helped me i really appreciate it @boussadjrabrahim . I updated my post with the solutionShortage
welcome ,you could post the update as answer for future askersRetrospection
S
14

[UPDATE] I have found the solution thanks to @boussadjrabrahim My working code look like this:

export default {
    props: ['listType'],
    components: {
        addrow: AddRow
    },
    computed: {
        ...mapGetters({
            current: 'Dropdown/current'
        }), 

        ...mapState({
            list (state, getters) {
                return getters[`${this.listType}/list`]
            }
        })
    }
}
Shortage answered 30/9, 2018 at 13:35 Comment(1)
Works great for getters. Any thoughts on how to do it for actions?Equipollent
E
5

You can also use this.$store for complete access to the store. So, list would become

export default {
    props: ['listType'],
    computed: {
        list() {
            return this.$store.getters[`${this.listType}/list`]
        }
    }
}

Use the dispatch method to trigger an action, like so

export default {
    props: ['listType'],
    methods: {
        sortList(order) {
            this.$store.dispatch(`${this.listType}/list`, order)
        }
    }
}
Equipollent answered 9/4, 2019 at 22:34 Comment(0)
L
0

What I found that worked was essentially rolling your own mapGetters method in the created() stage of the lifecycle.

Note that this solution has NOT been fully vetted and I have no idea what, if any "gotchas" it may create. As always, caveat emptor.

export default {
  props: ['listType'],
  components: {
    addrow: AddRow
  },
  created() {
    // This can be configured a number of ways, but for brevity:
    const mappableGetters = {
      list: `${this.listType}/list`,
      current: 'Dropdown/current'
    }

    Object.entries(mappableGetters).forEach(([key, value]) => {
      // Dynamically defines a new getter on `this`
      Object.defineProperty(this, key, { get: () => { return this.$store.getters[value] } })
    })

    // Now you can use: `this.list` throughout the component
  },
  computed: {
    // Roll your own mapper above in `created()`
    // ...mapGetters({
    //   list: `${this.listType}/list`,
    //   current: 'Dropdown/current'
    // })
  }
}
Laicize answered 21/1, 2022 at 21:9 Comment(1)
how is this solution going to retain the same reactivity as computed props?Raychel

© 2022 - 2024 — McMap. All rights reserved.