Reputation: 1051
I'm trying to check each comment and comment reply made by the user and check if they made the comment more than 30 mins ago then they can't edit it, however the way I'm doing it isn't working and I'm getting this error
[Vue warn]: You may have an infinite update loop in a component render function.
This is the code in question
<div v-for="comment in forum.comments">
<el-card shadow="never">
//check for other things
//set the comment info and layout
<div style="text-align: end" v-if="comment.user_id === $page.auth.user.auth.user.id">
{{minutes(comment)}}
<div v-if="editRemove === false" class="btn-link-edit action-button"
@click="edit(comment)">
<i class="fas fa-pencil-alt"></i>
</div>
</div>
<div v-for="reply in comment.replies">
//check for other things
//set the reply info and layout
<div style="text-align: end" v-if="reply.user_id === $page.auth.user.auth.user.id">
{{minutes(reply)}}
<div v-if="editRemove === false" class="btn-link-edit action-button"
@click="edit(reply)">
<i class="fas fa-pencil-alt"></i>
</div>
</div>
</div>
</el-card>
</div>
data return
editRemove: false,
method
minutes(item) {
var minutes = moment().diff(moment(item.comment_time), 'minutes');
if (minutes >= 30) {
this.editRemove = true;
} else if (minutes <= 29) {
this.editRemove = false;
}
}
What should I do to fix this?
Upvotes: 1
Views: 956
Reputation: 73337
As I mentioned in comment, you are constantly changing the one and the same variable this.editRemove
so change detection is happening and causes therefore something similar to an infinite loop. As also mentioned, I would make child component(s) for comments and replies. Though I said you can use a computed property, that won't work when thinking about it a second time ;) since it's not reactive. So I'd use an interval in the child component to check once a minute the amt of minutes that have passed since comment/reply has been posted.
So I would create a child, let's say Comment
, pass the current comment
in the v-for to the child:
<div v-for="comment in forum.comments">
<Comment :comment="comment"/>
</div>
Then the child would have the button and checks the time and whether to display edit button or not:
<button v-if="isEdit" @click="editComment">Edit</button>
isEdit
is determined on component creation, and after that, every 60 seconds. When destroying component, remember to clear the interval.
Child:
props: {
comment: Object
},
data() {
return {
isEdit: Boolean,
interval: null
};
},
methods: {
editComment() {
console.log(this.comment)
// do your magic
},
checkTime() {
var minutes = moment().diff(moment(this.comment.comment_time), "minutes");
if (minutes >= 30) {
this.isEdit = true;
// here you could also already clear the interval, since it won't change
} else if (minutes <= 29) {
this.isEdit = false;
}
}
},
created() {
this.checkTime();
this.interval = setInterval(() => {
this.checkTime();
}, 60000);
},
beforeDestroy() {
clearInterval(this.interval);
}
This demo is just for comments, but the same would be for replies.
CODESANDBOX, for the demo I made some changes to the interval and changed minutes to seconds. So after 10 seconds the 2 other buttons should appear.
Upvotes: 1