Vuex getters with params - vue.js

I am wondering why can't I use vuex getter with property with default value like this:
getters: {
getTest: (state, property = 'current') => {
return state.test[property]
}
}
and when I use it like this getTest.includes('something') it doesn't work but if I use it like this getTest().includes('something') it works?
Since when there are no params used it works without ()

https://vuex.vuejs.org/guide/getters.html#method-style-access
getters: {
getTest: (state) => (property = 'current') => {
return state.test[property]
}
}
// example usage
this.getTest().includes('something')

The second argument of the getters is the other getters :
Getters will also receive other getters as the 2nd argument
(https://vuex.vuejs.org/guide/getters.html#property-style-access)
So your property parameter will be an array, thus state.test[property] always returns undefined
To use a getter as a function with parameters, you need to make your getter return a function, as shown here: https://vuex.vuejs.org/guide/getters.html#method-style-access

getters: {
getCarteiraPeloId: (state) => (id) => {
return state.carteiras.find(thing => thing.id === id) || { nome: 'Não Encontrado' }
}
That is it.

Related

Vuex Getter Hook with Params

I defined a vuex getter function with parameter like this:
const getters = {
getProjectById: (state) => (id) => {
return state.projects.find(project => project.id === id)
}
}
Now, i want to use this getter in my component, but i couldn't find a way to pass the parameter to the getter.
Here is my getter hook computed property:
computed: {
...mapGetters(["currentUserPhoto","getProjectById"])
},
Is it possible to pass Id parameter which is come from router, to "getProjectId" getter? If is possible, what is the best way to do it?
Add another computed property called projectById which takes the route param as parameter and returns the project :
computed: {
...mapGetters(["currentUserPhoto","getProjectById"]),
projectById(){
return this.getProjectById(this.$route.params.id)
}
},

How can I send parameter with getters in nuxt?

I want send id with $route.params.id in getters but it does not work!
In my component I have blogs object; I want save this.$route.params.id in blogId and then pass it with my getters method like this:
created() {
const blogId = this.$route.params.id;
console.log(blogId); ////1
this.blog=this.$store.getters.getBlogById(blogId);
console.log(this.blog);
},
but
console.log(this.blog) is undefined
when I send a number like this:
$store.getters.getBlogById(2)
it works and console.log(this.blog) print my object
What should I do?
my getters:
const getters = {
allBlogs: state => state.blogs,
getBlogById: (state) => (id) => {
return state.blogs.find(blog => blog.id == id)
}
}
const blogId = this.$route.params.id - is a string, and in getter your are using ===, I think that's the reason.

How to return filtered array with vuex getters?

I try to return filtered array with VUEX getters but it send me this
ƒ (region) {
return state.cities.filter(function (city) {
return city.region === region;
});
}
I dont understud why it happend; hope somebody could help me.
My code
VUEX:
getCities: state => region => {
return state.cities.filter(city => city.region === region);
}
App.vue
test(a){
console.log(this.getCities(a))
}
You can import mapGetters or access the store object through this.$store.getters.getCities(a)
you can read more here:
https://vuex.vuejs.org/guide/getters.html#property-style-access
I've found the solution. The right way to call VUEX getters with params should be this.$store.getters.yourGetter()(params) or with ...mapGetters. The main point that the getters with params return function and you can pass params in it.
For example how it works
getter:
getCities: state => region => {
return state.cities.filter(city => city.region === region);
}
import and call:
methods: {
...mapGetters('location', [ 'getCities' ]),
test(params){
console.log(this.getCities()(params))
}
}

Vuex reactive mapGetters with arguments passed through

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 })
}
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)
}
},

mapState with setter

I would like to assign setter methods via mapState. I currently use a workaround where I name the variable that I am interested in (todo) as a temporary name (storetodo) and then refer to it in another computed variable todo.
methods: {
...mapMutations([
'clearTodo',
'updateTodo'
])
},
computed: {
...mapState({
storetodo: state => state.todos.todo
}),
todo: {
get () { return this.storetodo},
set (value) { this.updateTodo(value) }
}
}
I would like to skip the extra step and define the getter, setter directly within mapState.
Why would I want to do this?
The normal approach would be use mapMutations/mapActions & mapState/mapGetters
without the computed get/set combination that I have illustrated above and to reference the mutation directly in the HTML:
<input v-model='todo' v-on:keyup.stop='updateTodo($event.target.value)' />
The getter/setter version allows me to simply write:
<input v-model='todo' />
You can't use a getter/setter format in the mapState
what you can try is directly return the state in your get() and remove mapState from the computed property
computed: {
todo: {
get () { return this.$store.state.todos.todo},
set (value) { this.updateTodo(value) }
}
}
Here is a related but not same JsFiddle example
This is my current workaround. Copied from my personal working project
// in some utils/vuex.js file
export const mapSetter = (state, setters = {}) => (
Object.keys(state).reduce((acc, stateName) => {
acc[stateName] = {
get: state[stateName],
};
// check if setter exists
if (setters[stateName]) {
acc[stateName].set = setters[stateName];
}
return acc;
}, {})
);
In your component.vue file
import { mapSetter } from 'path/to/utils/vuex.js';
export default {
name: 'ComponentName',
computed: {
...mapSetter(
mapState({
result: ({ ITEMS }) => ITEMS.result,
total: ({ ITEMS }) => ITEMS.total,
current: ({ ITEMS }) => ITEMS.page,
limit: ({ ITEMS }) => ITEMS.limit,
}),
{
limit(payload) {
this.$store.dispatch({ type: TYPES.SET_LIMIT, payload });
},
},
)
},
}
now you can use the v-model bindings. l
Another way of approaching that is using store mutations like below:
//in your component js file:
this.$store.commit('setStoretodo', storetodo)
Assuming you define setStoretodo in mutations of your vuex store instance (which is something recommended to have anyways):
//in your vuex store js file:
state:{...},
actions: {...}
...
mutations: {
setStoretodo(state, val){
state.storetodo = val
},
...
}
...
That keeps the property reactive as mapState will grab the updated value and it will be rendered automatically.
Surely, that's not as cool as just writing this.storetodo = newValue, but maybe someone will find that helpful as well.