Vuex - mapGetters et al but mapping by parameter - vue.js

I'm trying to create a general filter component which get's it's data from the store
Right now, I'm using mapGetters like so
...mapGetters({
items: 'filters'
}),
But I would like to be able to generalize this to which getter I'm mapping
props: {
filterType: String
},
computed: {
...mapGetters({
items: this.filterType
}),
}
This gives me the following error
Cannot read property 'nombre' of undefined
I know that I can do:
computed: {
items: function () {
return this.$store.getters[this.filterType]
}
}
but I just wanted to check if there is a way to use the properties of the vue instance with the mapGetters, or if you need to strictly hardcode the getters names inside

Maybe that's what you are looking for (or at least closest to the use of mapGetters):
props: {
filterType: String
},
computed: {
...mapState({
items(state, getters) {
return getters[this.filterType];
}
})
}

Related

How to use a Nuxt component to pass a parameter to a vuex getter method? (while maintaining three dot notation)

GOAL: I would like to watch a vuex state object (MATCH_DATA) for changes, specific to the value of a prop (topicId). So, I would like to set the watcher to watch MATCH_DATA[topicId]. And whenever MATCH_DATA[topicId] updates, I'd like to call a function (in this early case just logging it).
However, since MATCH_DATA is a getter how would I pass a parameter to it? The vuex getter does not seem to be designed to take in parameters. I have seen some examples by explicitly calling this.$store.state.etc.etc. but is there a way to do this while retaining the three dot notation I currently have?
Or, is there some better way of achieving this goal that does not involve a vuex getter?
Current Code:
Nuxt component:
<script>
import { mapGetters, mapActions } from 'vuex';
export default {
props: ['topicId'],
computed: {
...mapGetters('sessionStorage', ['MATCH_DATA']),
},
watch: {
MATCH_DATA (newMatchData, oldMatchData) {
console.log(newMatchData);
}
},
mounted() {
this.SUBSCRIBE_TO_TOPIC(this.topicId);
},
methods: {
...mapActions('sessionStorage', ['SUBSCRIBE_TO_TOPIC'])
}
}
vuex store:
/* State */
export const state = () => ({
MATCHES: {},
});
/* GETTERS */
export const getters = {
MATCH_DATA: (state) => {
return state.MATCHES;
},
};
Your getter can simply return a function like this:
export const getters = {
MATCH_DATA: (state) => {
return topicId => {
// return something
}}
},
};
Then you can create a computed property to access those getter:
export default {
computed: {
...mapGetters('sessionStorage', ['MATCH_DATA']),
yourComputedProperty () {
return this.MATCH_DATA(this.topicId)
}
}
}
Then you can watch the computed property to react on changes.
watch: {
yourComputedProperty (newData, oldData) {
console.log(newData);
}
}

Vuex: importing a single state from an object

I have a simple store:
UsersStore.js
state() {
return {
users: {
name: '',
userHasPermissions: false,
}
}
}
I am trying to use mapState to have the state accessible in my component. When I import the entire User object of the store like below, it works:
App.vue
computed: {
...mapState('users', {
myUser: 'user'
}
but I just want to import the userHasPermissions state but when I do the following, it does not seem to work:
App.vue
computed: {
...mapState('users', {
hasPerms: 'user.hasPermissions'
}
You can use vuex getters to get a specific property from any store object
state() {
return {
users: {
name: '',
userHasPermissions: false,
}
}
},
getters: {
userHasPermission(state) {
return state.users.userHasPermission || false;
}
}
Now you can use mapGetters to map store getters to your vue component
computed: {
...mapGetters({
hasPerms: "userHasPermission"
})
}
If you want to avoid using mapGetters and getters and use mapState, then you need to define a computed function inside your mapState to fetch the desired property
computed: {
...mapState({
hasPerms: (state) => state.users.userHasPermission
})
}

Mutating Vuex array that is used in different component

In first component I have a function that changes the array using the value that is stored in VueX
methods: {
//get a function that changes the pickedlist array that is stored in vuex store
...mapActions([
'updatePickedDates'
]),
...mapGetters([
'dates'
]),
resetArray() {
this.updatePickedDates(this.dates}
}
In another component
I use getter from VueX that is passed on this array:
computed: {
...mapGetters(["managementNews"])
}
However when resetArray() function runs I get error that
state.pickedDates.includes is not a function
Here are the getters and mutations in my VueX store:
mutations: {
mutatePickedDates: (state, payload) => {
state.pickedDates=payload
}
},
actions: {
updatePickedDates({commit}, payload) {
commit('mutatePickedDates', payload)
}
},
modules: {
},
getters : {
//get news that are of type management
managementNews: function(state) {
return state.news.filter(i => i.type === "management" && state.pickedDates.includes(i.date));
},
dates: state => {
return state.dates
},
pickedDates: state => {
return state.pickedDates
}
},
In this case this.dates is a function and not an array. The error indicates that it's not undefined, yet it doesn't have includes method.
mapGetters should provide getters for computed properties. There's no way how mapGetters could be applied to methods and make this.dates to be an array.
It should be:
methods: {
...mapActions([
'updatePickedDates'
])
},
computed: {
...mapGetters([
'dates'
]),
}

Value in props, using in mapState can not working Vue.js

I want to pass value from props and using it as the namespace in mapState, then it show error: 'Error while initializing app TypeError: Cannot read property 'store' of undefined'
Here my code:
ParentComponent: <Editor store="store-test" />
ChildComponent:
export default {
props: ['store'],
computed: {
mapState(`${this.store}`, ['data'])
}
}
But i replace this.store = store-test, i have receive data i want.
And i dont know how to using
...mapMutations({
function() {
}
})
is same
...mapState({
data(state) {
return state[this.store].data;
},
})
Because mapState returns its value for your computed definition at compile time, you cannot use props as they are only assigned at runtime.
You will have to use
computed: {
data () {
return this.$store.state[this.store].data
}
}
If you want, you can still use mapState however you cannot use the prop value as a namespace string
mapState({
data1 (state) { // 👈 note: cannot be an arrow function
return state[this.store].data1
},
data2 (state) {
return state[this.store].data2
}
})

Vue computed syntax error with mapState

I have this code:
computed: {
mapState(["appErrors", "user", "profilesFor"]),
compiledData () {
return {
template: `<p>${this.data}</p>`
}
}
}
Basically I am using Vuex and it has mapState but I also want to define my own computed functions so I changed
computed: mapState(["appErrors", "user", "profilesFor"]) --Works
to
computed: {
mapState(["appErrors", "user", "profilesFor"]),
compiledData () {
return {
template: `<p>${this.data}</p>`
}
}
}
But it doesn't work. How would I fix this issue?
The mapState helper provides an object containing computed getter functions.
Use the spread operator to include each of those functions in your computed object:
computed: {
...mapState(["appErrors", "user", "profilesFor"]),
compiledData () {
return {
template: `<p>${this.data}</p>`
}
}
}