Up and downvotes are functional yet I'd like to do a check like "If the user is a downvoter or an upvoter" and do the right thing which is explained below
upvote: function(postId) {
check(this.userId, String);
check(postId, String);
var affected = Posts.update({
_id: postId,
upvoters: {$ne: this.userId}
},{
$addToSet: {
upvoters: this.userId
},
$inc: {
upvotes: 1
}
});
if (! affected)
throw new Meteor.Error('invalid', "You already up-voted this post");
},
downvote: function(postId) {
check(this.userId, String);
check(postId, String);
var affected = Posts.update({
_id: postId,
downvoters: {$ne: this.userId},
}, {
$addToSet: {
downvoters: this.userId
},
$inc: {
downvotes: 1
}
});
if (! affected)
throw new Meteor.Error('invalid', "You already down-voted this post");
},
With my code above, users can upvote and downvote once, but they can do both...
I wrote the code for what happens if a user is a downvoter and clicks upvote but I couldn't figure out how to check if the user is a downvoter or an upvoter.
$pull: {
downvoters: this.userId
},
$addToSet: {
upvoters: this.userId
},
$inc: {
downvotes: -1
},
$inc: {
upvotes: 1
});
EDIT: Even though the accepted answer works fine, I found an issue with it. When you click fast, it might increment the vote count 2-3 times. Instead of incrementing vote count, I only insert userId and simply count how many IDs there are inside the upvoters/downvoters array which gives the same result & it never inserts the same userId twice.
Inside the helpers for the count:
return this.upvoters.length
Also, inArray is a useful tool for checking if the value you have is inside an array.
if($.inArray(Meteor.userId(), this.upvoters)) //gives true if the current user's ID is inside the array
You will have to fetch the post and see if it contains the user's id in its downvoters
array:
var post = Posts.findOne(postId);
if (post.downvoters && _.contains(post.downvoters, this.userId)) {
Posts.update({
_id: postId
},
{
$pull: {
downvoters: this.userId
},
$addToSet: {
upvoters: this.userId
},
$inc: {
downvotes: -1,
upvotes: 1
}
}
});
}