Home > Mobile >  mongo DB always update first document
mongo DB always update first document

Time:09-05

I have a posts collection that has array of likes.I want to push object into likes array if user have not liked and pull if user has liked the post.I test my API but it always update first document of collection though I provided postId of other document.

schema.js

likes: [
    {
      userId: String,
      isNotified: {
        type: Boolean,
        default: false,
      },
      email: String,
      types: String,
    },
  ],

API

router.post("/like", (req, res) => {
      postModel.find(
      {
        "_Id": req.body.postId,
        "likes.userId": req.body.userId,
      },
      (err, doc) => {
        // console.log(doc)
       if (!doc.length) {
          postModel.updateOne(
            { "_Id": req.body.postId,},
            {
              $push: {
                likes: {
                  userId: req.body.userId,
                  email: req.body.email,
                  // types: req.body.types,
                },
              },
            },
            (err, doc) => {
               res.send("like");
            }
          );
        } else {
          // console.log("pull")
          postModel.find(
            {
              "_Id": req.body.postId,
              "likes.userId": req.body.userId,
            },
            (err, doc) => {
              doc.map((e) => {
                e.likes.map((x) => {
                  if (x.userId == req.body.userId) {
                    postModel.updateOne(
                      {
                        "_Id": req.body.postId,
                        "likes.userId": req.body.userId,
                      },
                      {
                        $pull: {
                          likes: {
                            userId: req.body.userId,
                            email:req.body.email
                          },
                        },
                      },
                      (err, doc) => {
                        
                          res.send("unlike");
                        
                      }
                    );
                  }
                });
              });
            }
          );
        }
        // res.send(doc);
      }
      
    );
  // });
});

postman request

           {
               "email":"[email protected]",
               "types":"like",
                "postId":"6312c2d1842444a707b6902f",
                 "userId":"631452d0e1c2acf0be28ce43"
      
         }

How to fix this,suggest an advice.Thanks in advance.

CodePudding user response:

I'm not sure if I undrestand the logic, but here are couple of things that I think you can improve:

  1. You are using find method to get a single document, you should use findOne method which return a single document (if exists) and not an array of documents. But in general when you have the _id value of a document, it's better to just use findById method which is much faster.
  2. When you find a document, you can just modify it and call it's save method to write your changes to the database, there is no need to use updateOne. (please note that partital update has many advantages but in your case they don't seem necessary, you can read about it online.)

your API code can be something like this:

router.post("/like", (req, res) => {
  const postId = req.body.postId
  const userId = req.body.userId

  postModel.findById(postId) // get the post
    .then(post => {
      if (post) { // check if post exists

        // check if user has already liked the post 
        if (post.likes.find(like => like.userId == userId)){
          // user has already liked the post, so we want to
          // remove it from likes (unlike the post). 

          // I know this is not the best way to remove an item 
          // from an array, but it's easy to understand and it
          // also removes all duplications (just in case).
          post.likes = post.likes.filter(like => like.userId != userId)

          // save the modified post document and return
          return post.save(_ => {
            // send success message to client
            res.send("unlike")
          })

        } else {
          // user has not liked the post, so we want to add a
          // like object to post's likes array
          post.likes.push({
            userId: userId,
            email: req.body.email // you can other properties here
          })

          // save the modified post document and return
          return post.save(_ => {
            // send success message to client
            res.send("like")
          })
        }
      } else { // in case post doesn't exist
        res.status(404).send("post not found.")
      }
    })
    .catch(err => {
      // you can handle errors here
      console.log(err.message)
      res.send("an error occurred")
    })
})

I didn't run the code, but it should work.

  • Related