Search code examples
node.jsmongodbexpressmongoosemongoose-populate

How to save the user document when creating a new post?


So, I have figured out the previous problems and just need to populate the user document with posts. Currently user document looks like this:


        {
            "posts": [],
            "_id": "5e75cf827ef14514f69c6714",
            "username": "dio",
            "email": "dio123@gmail.com",
            "password": "$2b$10$fwV.KaZG.5tjtmMxQ9NNE.7.XAh6pzLFgf85z9BpPVOgFguR2inGO",
            "createdAt": "2020-03-21T08:25:38.459Z",
            "updatedAt": "2020-03-21T08:25:38.459Z",
            "__v": 0
        }

So, I did this while creating the post to be able to populate it later.

newPost: (req, res) => {

    const data = {
        title: req.body.title,
        content: req.body.content,
        user: req.user.userId
    }

    Post.create(data, (err, newPost) => {
        console.log(data, "data")
        if (err) {
            return res.status(500).json({ error: err })
        } else if (!newPost) {
            return res.status(400).json({ message: "No Post found" })
        } else if (newPost) {
            User.findById(req.user.userId, (err, user) => {
                user.Posts = user.Posts.concat(newPost._id)
                return res.status(200).json({ newPost, user })
            })
        }
    })
}

After doing this when i return user from the above return statement, it looks like this:

{ 
    posts: [ 5e75d89fa048e321f704453b ],
    _id: 5e75cf827ef14514f69c6714,
    username: 'dio',
    email: 'dio123@gmail.com',
    password: '$2b$10$fwV.KaZG.5tjtmMxQ9NNE.7.XAh6pzLFgf85z9BpPVOgFguR2inGO',
    createdAt: 2020-03-21T08:25:38.459Z,
    updatedAt: 2020-03-21T08:25:38.459Z,
    __v: 0
 }

Everytime I create a new post, I exprect the posts array to contain the objectIDs of the posts that the user has just created, but it's only pushing the latest post's objectId. Why does it not remembering the previous ones?

Also, I want to get the user's posts:

        getUserPosts: async (req, res) => {
            try {
              const user = await User.findById(req.params.id).populate("posts");

              if (!user) {
                return res.status(400).json({ error: "No user" });  
              }

              return res.status(200).json({ userPosts: user.posts });
            } catch (err) {
              return res.status(500).json({ error: "Server error" });
            }
        }

Since, the user document saved in the database has empty array of posts I am not able to populate it. Please help.


Solution

  • After you add the new post's id to the user's posts array, you need to save the user:

      Post.create(data, (err, newPost) => {
        console.log(data, "data");
        if (err) {
          return res.status(500).json({ error: err });
        } else if (!newPost) {
          return res.status(400).json({ message: "No Post found" });
        } else if (newPost) {
          User.findById(req.user.userId, (err, user) => {
            user.posts.push(newPost._id);
            user
              .save()
              .then(() => {
                return res.status(200).json({ newPost, user });
              })
              .catch(err => {
                return res.status(500).json({ error: err });
                console.log(err);
              });
          });
        }
      });
    

    As I remember in your previous questions, the name of the field for posts was posts not Posts in the user schema, so the following line is important, also we use push method instead of concat:

    user.posts.push(newPost._id);
    

    After this, we just need to save the user with save method, since save method returns a promise I added then catch blocks.