I have a Vuex store with an object called data in the state of a module called users. This object maps user ids to users, and it begins empty.
Then I have a message-list component that renders message components with a passed property called authorId. This message will use the id try to get the author's email by searching the data object in the store. If it doesn't find it, it will dispatch an action that will fetch the user from the server and commit a mutation to add the id and user to the data object in the store. Note that for now every message has the same authorId and that the server fetching logic works as expected.
Users module
state: { data: {} },
mutations: {
setUser(state, user) {
Vue.set(state.data, user._id, user);
},
},
actions: {
fetchUser({ commit }, id) {
userService.find({ _id: id }).then((response) => {
commit('setUser', response.data[0]);
});
}
Message component
<template>
<div class="message">
<strong v-if="author">{{author.email}}</strong>: {{text}}
</div>
</template>
<script>
export default {
name: 'messages',
props: ['text', 'authorId'],
created() {
this.resolveAuthor();
},
computed: {
author() {
return this.$store.state.users.data[this.authorId];
},
},
methods: {
resolveAuthor() {
if (!this.author) this.$store.dispatch('fetchUser', this.authorId);
},
};
</script>
The expected behaviour would be to see just one setUser mutation because the first message component instance will fetch and populate the store, and the next instances would use that stored value. I see one mutation per message meaning that the call to this.author in created() or mounted() is always undefined, maybe I would expect this in the first message but not in the next ones as the store is already populated.
Doing console.log(Object.keys(this.$store.state.users.data)) in every created() or mounted() of each message instance reveals the data object is empty but I can see it has one key (authorId) and the user value in the vue dev-tools and also if I console.log(this.$store.state.users.data).
Moreover, if in the template I render {{this.user}} it will print the data correctly on every message. Also if I re-save any file, hot reloading will now print all the console.log(Object.keys(this.$store.state.users.data)) I did before again but now showing the key and value I expect instead of showing an empty object.
Edit 2018-10-24 I hope that the working repository helps someone: https://github.com/niklabaz/chatter