I am somewhat new to this, so if I am on the completely wrong track feel free to let me know.
I have the following post schema.
var Post = new Schema( {
description: {
type: String,
default: '',
required: 'Please type a description',
trim: true
},
likeCount: {
type: Number,
default: 0
},
url: {
type: String,
default: '',
required: 'Unable to find photo',
trim: true
},
created: {
type: Date,
default: Date.now
},
user: {
type: Schema.ObjectId,
ref: 'User',
required: 'Unable to verify user'
},
comments: {
type: [Comment]
},
//Dynamically added values
hasLiked: {
type: Boolean
}
});
And the following Like schema
var Like = new Schema({
created: {
type: Date,
default: Date.now
},
user: {
type: Schema.ObjectId,
ref: 'User'
},
post: {
type: Schema.ObjectId,
ref: 'Post'
}
});
When I show a user a list of posts I need to indicate whether they have previously "liked" a post, so I am trying to pull the posts, then iterate through them to determine if the person has liked it and update the value in the Post. I'm not getting any errors, but it's also not updating the hasLiked value. I put the hasLiked value into my Mongoose model because I can't just add a value on the fly before returning my results. I don't store an actual value for that in the DB because it would obviously be different for every person that viewed the post.
exports.list = function(req, res) {
Post.find().sort('-created').populate('user', 'displayName')
.exec(function (err, posts) {
if (err) {
return res.status(400).send({
message: errorHandler.getErrorMessage(err)
});
} else {
for (var i = 0; i < posts.length; i++) {
Like.find({ 'post': posts[i]._id, 'user': req.user.id }).exec(function (err, like) {
if (err) {
return res.status(400).send({
message: errorHandler.getErrorMessage(err)
});
} else {
if (like.length == 0)
posts[i].hasLiked = false;
else
posts[i].hasLiked = true;
}
});
}
res.jsonp(posts);
}
});
};
Node is async language. So your mistake here is that when you query to find if the user liked the post:
Like.find({ 'post': posts[i]._id, 'user': req.user.id }).exec(function (err, like)
the answer will return after you return the answer to the client. In other words, line res.jsonp(posts); performed before the answer from mongo returned and enters to the callback. Thats why it isn't working for you.
To handle with async methods, I suggest you to use a third-party library, such as async or q. Here is one solution for you with Q library:
var Q = require('q');
var promises = [];
posts.forEach(function(post) {
promise = Q(Like.find({ 'post': post._id, 'user': req.user.id }).exec())
.then(
function(like) {
if (like.length == 0)
post.hasLiked = false;
else
post.hasLiked = true;
}
}
,function(err) {
//handle error
});
})
Q.all(promises)
.then(function() {
return res.jsonp(posts);
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With