Vuex Getter Hook with Params - vue.js

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

Related

Vuex getter with an argument and computed property

I'm having trouble understanding how the code from a tutorial works.
I have the EventComponent component, which displays information about the event.
It uses a computed property which accesses Vuex store.
<h4>This event is {{ getEvent(1) }}.</h4>
export default {
computed: {
getEvent() {
return this.$store.getters.getEventById
}
}}
And this is my Vuex index.js file:
export default createStore({
state: {
events: [{id: 1, title: "Last day"}]
},
mutations: {},
getters: {
getEventById: state => id => {
return state.events.find(event => event.id === id)
}
},
actions: {},
modules: {}
})
The event info is displayed correctly. However, I'm confused by
How the computed property is able to accept an argument
How that argument is passed to the store getter, when the getter is not explicitly called with that argument
Could you help me understand this?
How the computed property is able to accept an argument
Since getEvent just returns this.$store.getters.getEventById (which is a getter for a function), getEvent also returns a function, and can therefore be called the exact same way.
How that argument is passed to the store getter, when the getter is not explicitly called with that argument
Actually, the getter is indeed being called with that argument. As mentioned above getEvent is effectively an alias for this.$store.getters.getEventById, so getEvent(1) is the same as this.$store.getters.getEventById(1).
Return a function from the computed property that takes the id as parameter:
<h4>This event is {{ getEvent(1) }}.</h4>
export default {
computed: {
getEvent() {
return (id)=>this.$store.getters.getEventById(id)
}
}}

Vuex getters with params

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.

Get a value from an observer in a Vuex getter

I have namespace module with a getter method called allItems() to get an array of values from a normalized state.
...
getters: {
allItems(state, getters, { entities }) {
return state.items.map(function (item){
return {...entities.product[item]};
});
}
}
When I try to get other elements, it gives me the "you can't call some property from undefined element" error.
If I put console.log(entities) I can see the array of elements and when I put console.log(entities.products) I got an observer {__ob__: Observer} with the data inside but when I put console.log(entities.products[1]) for example, I got undefined. What should I do to solve this?
I solved this creating a method getter called getEntityById like this
getters: {
getEntityById: (state) => (entity, id) => {
return state[entity][id];
}
}
And calling it on a map function

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

computed property not reading data initialized in created

I am not sure when computed property (in vue lifecycle) comes. Let's say I have a method that I run in created() as:
created () {
getSomething()
}
Inside getSomething() I fetch data and fill my data property as:
getSomething(){
axios.get(...) { this.info = response.data }
}
Now, in computed properties, I do:
computed: {
doSomething () {
this.info.forEach(item => {})
}
}
But, inside my computed I get forEach is undefined, as if this.info is not an array or has not be filled.
What am I doing wrong? are computed props called before created() or something?
try something like this
getSomething(){
return axios.get(...) { this.info = response.data }
}
then you can use the promise returned in created method like this....
created () {
getSomething().then( () => {
doSomething()
}}
}
You could utilise Vuex' state management...
Vuex has :
Dispatches
Actions
Mutations
Getters
What i am thinking is, on your page load, map an action to the store that makes a call to your axios service and after it returns, commit a mutation that stores the response to the store...
then you can map the state to your component and retrieve the data.
This might not be the quickest answer but if you are expecting to need the response data from the axios request, it might be worth putting it into some sort of state management :-)