Newbie question here with Vuex. Probably doing something wrong. I have this simple store:
export default new Vuex.Store({
strict: process.env.NODE_ENV !== 'production',
state: {
items: []
},
getters: Object.assign({}, itemGetters),
mutations: Object.assign({}, itemMutations),
actions: Object.assign({}, itemActions),
});
With the getters being like this:
export const itemGetters = {
allItems: state => state.items,
itemById: (state, getters) => id => getters.allItems.filter(s => s.id === id)[0],
};
Now, I have this view which has a nested view in it. Basically an information modal for each item.
If I click on the link, I expect to go and see the element modal with the item filled.
export default {
name: 'Landing',
computed: {
items() {
return this.$store.getters.allItems;
}
},
created() {
if (this.items.length === 0) {
this.$store.dispatch('allItems');
}
}
};
Now, entering that view works as expected and if I click on the nested view, which is as follows:
<template>
<div class="text">
<h1 class="heading">{{ item.title }}</h1>
</div>
</template>
<script>
export default {
name: 'InfoModal',
props: ['id'],
computed: {
item() {
return this.$store.getters.itemById(this.id);
}
}
};
</script>
It does work too. However, it doesn't work when I just reload the page and errors due to item
not being there yet.
Thing is I could do the same and add an action to fetch the item from the API if it's not there yet but I don't really see the point because I'll have all of them eventually.
What do I need to do here?
The thing is the computed properties get evaluated first pretty early in the components lifecycle.
If you know that the item will eventually (and quickly) be there, simply return a default value in the computed when the item isn't there yet, so Vue has something to render (even if empty) in this first execution:
computed: {
item() {
return this.$store.getters.itemById(this.id) || {}; // added {} as default.
}
}
The computed will be automatically re-evaluating (because the getter will) as soon as the item becomes available.