\n","author":{"@type":"Person","name":"Leos Literak"},"upvoteCount":1,"answerCount":2,"acceptedAnswer":{"@type":"Answer","text":"
You forgot about a reactivity again. Use Vue.set to set a new prop in a comments
state prop:
Vue.set(state.comments, comment._id, comment);\n
\ninstead of
\n state.comments[comment._id] = comment;\n
\n","author":{"@type":"Person","name":"Anatoly"},"upvoteCount":1}}}Reputation: 9406
I wanted to prepare minimum reproducible sandbox for my issue. I forked my previous sandbox and removed the code that was irrelevant for new case. But one feature stopped working and I have no idea why. The code looks the same and console.log shows the code is updated. Why does it work in one sandbox and does not work in the second?
The original sandbox: https://codesandbox.io/s/frosty-taussig-v8u4b Try to click on some button with numbers, it gets incremented instantly.
Minimized sandbox: https://codesandbox.io/s/nervous-breeze-ejznz. If you click on a button with number, nothing happens until you reload the screen.
I would like to understand this behaviour. I do not see a reason why the same source code behaves differently.
Mutation:
SET_VOTE: (state, payload) => {
console.log("SET_VOTE");
const { commentId, vote } = payload;
const comment = state.comments[commentId];
if (vote === 1) {
comment.up += 1;
} else {
comment.down += 1;
}
console.log(comment);
}
Action:
COMMENT_VOTE: async (context, payload) => {
console.log("COMMENT_VOTE", payload);
const mutation = {
commentId: payload.commentId,
vote: payload.vote
};
context.commit("SET_VOTE", mutation);
}
Comment.vue
<b-button v-on:click="upvote" class="mr-1">
{{ comment.up }}
</b-button>
async upvote() {
await this.$store.dispatch("COMMENT_VOTE", {
vote: 1,
commentId: this.comment._id
});
},
Upvotes: 1
Views: 61
Reputation: 9406
It finally works. The trick was:
data() {
return {
commentVotes: this.comment.votes,
};
computed: {
upvotes() {
return this.commentVotes.filter(vote => vote.vote === 1);
},
downvotes() {
return this.commentVotes.filter(vote => vote.vote === -1);
},
Upvotes: 0
Reputation: 22813
You forgot about a reactivity again. Use Vue.set to set a new prop in a comments
state prop:
Vue.set(state.comments, comment._id, comment);
instead of
state.comments[comment._id] = comment;
Upvotes: 1