Reputation: 2048
I'm trying to create computed properties using data pulled with the mapGetters function in vuex, but I'm always getting undefined, until the page/dom fully loads.
Here's an example for an isRegistered computed property that I use to hide/display certain buttons.
computed: {
...mapGetters(['solos', 'user']),
isRegistered () {
return this.solos.registered.indexOf(this.user._id) !== -1
}
}
Here is the HTML for buttons that use the isRegistered computed property.
<a href="#" class="register-button" v-if="!isRegistered">REGISTER NOW</a>
<a href="#" class="registered-button" v-if="isRegistered">REGISTERED</a>
I'm setting the getters via an action which I'm calling in the created function
created () {
this.getTournament('solos').catch(err => {})
}
Here's my action for setting the corresponding getters
getTournament: ({commit}, type) => {
return feathers.service('tournaments').find({
query: {
type: type,
status: 'registering'
}
}).then(tourney => {
commit(type.toUpperCase(), tourney.data[0])
})
}
Here's the corresponding mutation
const mutations = {
SOLOS (state, result) {
state.solos = result;
}
};
Here's the corresponding getter
const getters = {
solos (state) {
return state.solos
}
}
The issue I'm having is the value is initially showed as undefined until the PAGE/DOM is fully loaded, causing .indexOf to throw the following error:
TypeError: Cannot read property 'indexOf' of undefined
The only way I've been able to get this to work is to use an if statement on the computed property that checks if the state data has loaded yet.
isRegistered () {
if (this.solos._id) return this.solos.registered.indexOf(this.user._id) !== -1
}
This doesn't seem like a proper way of doing things. What am I doing wrong?
Upvotes: 11
Views: 7238
Reputation: 1066
The issue is probably about the vue lifecycle.
At the created hook, the computed properties, watchers and data of component are initialized (runs synchronously), but solos getter runs inside a promise (runs asynchronously), so the lifecycle continue without the promise get done.
When created hook is finished, the watchers was created, which means if data get changed, they will be reflected at the DOM, but only after the promise returns the result, the solos will be filled. So at the initialization of the app, the promise is not ended, but as soon it ends the data is updated and displayed.
A way to avoid this error is to use v-if="solos.registered"
, but I'm still searching for a better way to solve this.
Upvotes: 12