Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using mongoose lean after saving

So I am trying to add a key to a returned post. But I can't seem to get lean() to work. How can I manipulate the returned post after save?

I was thinking maybe I need to add lean to my findById like this Post.findById(req.params.id).lean().then(). But that didn't work, plus that only makes the first initial post mutable. It will say

post.save is not a function

if I do it like Post.findById(req.params.id).lean().then() as well

I want to only return the object about to be sent back to the client, I do not want they key saved in the actual document.

 Post.findById(req.params.id)
      .then(post => {
        if (
          post.likes.filter(like => like.user.toString() === req.user.id)
            .length === 0
        ) {
          return res
            .status(400)
            .json({ notliked: "You have not yet liked this post" });
        }

        // Get remove index
        const removeIndex = post.likes
          .map(item => item.user.toString())
          .indexOf(req.user.id);

        // Splice out of array
        post.likes.splice(removeIndex, 1);

        // Save
        post.save().then(post => {  
          post["liked"] = false;  <-------
          res.json(post);
        });
      })

edit

  Post.findById(req.params.id)
      .lean()
      .then(post => {
        if (
          post.likes.filter(like => like.user.toString() === req.user.id)
            .length === 0
        ) {
          return res
            .status(400)
            .json({ notliked: "You have not yet liked this post" });
        }

        // Get remove index
        const removeIndex = post.likes
          .map(item => item.user.toString())
          .indexOf(req.user.id);

        // Splice out of array
        post.likes.splice(removeIndex, 1);
        post["liked"] = false;
        res.json(post);
        // Save
        post.save();
      })

gives error

post.save is not a function

like image 568
Snoopy Avatar asked Aug 16 '26 01:08

Snoopy


1 Answers

You can simply do this by searching for the req.user.id inside the indexOf likes array

Post.findOne({ _id: req.params.id }).lean().then((post) => {
  if (post.likes.indexOf(req.user.id) !== -1) {
    post.isLiked = true
  }
  post.isLiked = false
  res.json(post)
})

Far better with the aggregation

Post.aggregate([
  { "$match": { "_id": mongoose.Types.ObjectId(req.user.id) }},
  { "$addFields": {
    "isLiked": { "$in": [mongoose.Types.ObjectId(req.user.id), "$likes"] }
  }}
])

EDIT :- If you want to update document then use update query

Post.findOneAndUpdate(
  { _id: req.params.id },
  { $pull: { likes: { user: req.user.id } }},
  { new: true }
).then((post) => {
  res.json(post)
})

Post Schema for likes

...
    likes: [
        {
          user: {
            type: Schema.Types.ObjectId,
            ref: "users"
          }
        }
      ]
...
like image 178
Ashh Avatar answered Aug 19 '26 02:08

Ashh