0

I want to access nested element from Mongo Schema. What I am trying to do is when user likes a comment of a user id should be pushed in the commentLikes array which is a child of comments if I make commentLikes as a seprate parent each comment have same number of likes for example if user A likes comment 1, his id will also be pushed in comment 2.

My Schema is:

const mongoose = require("mongoose")
const { ObjectId } = mongoose.Schema.Types

const postSchema = new mongoose.Schema({
    subject: {
        type: String,
        required: true
    },
    title: {
        type: String,
        required: true
    },
    body: {
        type: String,
        required: true
    },
    photo: {
        type: String,
        default: "https://res.cloudinary.com/bigbrain/image/upload/v1616608676/noQ_hvukdh.png"
    },
    likes: [{
        type: ObjectId,
        ref: "User"
    }],
    comments: [{
        text: String,
        postedBy: { 
            type: ObjectId, 
            ref: "User" 
        },
        commentLikes:[{
            type: ObjectId,
            ref: "User"
        }],
       
    }],
    
    postedBy: {
        type: ObjectId,
        ref: "User"
    },
    postDate:{
        type:String
    }
},{timestamps:true})

mongoose.model("Post", postSchema)

My Backend Code:

  router.put("/likecomment/:id/:comment_id",requireLogin,(req,res)=>{
    const comment = { _id: req.params.comment_id };
    Post.findByIdAndUpdate(req.body.postId,{
        $push:{comments:req.user._id
        }
    },{
        new:true
    }).exec((err,result)=>{
        if(err){
            return res.status(422).json({error:err})
        }
        else{
            console.log(result)
            res.json(result)
        }
    })
})

My Front end code is:

 const likeComment = (commentid) => {
        fetch(`/likecomment/${postid}/${commentid}`, {
            method: "put",
            headers: {
                "Content-Type": "application/json",
                "Authorization": "Bearer " + localStorage.getItem("jwt")
            },
            body: JSON.stringify({
                postId: commentid
            })
        }).then(res => res.json())
            .then(result => {
                const newData = data.map(item => {
                    if (item._id === result._id) {
                        console.log(result)
                        return result
                    }
                    else {
                        console.log(item)
                        return item
                    }
                })
                setData(newData)
            }).catch(err => {
                console.log(err)
            })

    }

I JUST WANTED TO ACCESS THE commentLikes which is inside comments in backend, I know my logic is correct

 Post.findByIdAndUpdate(req.body.postId,{
        $push:{comments:req.user._id
        }

I also tried accessing commentLikes by comments[commentLikes] but it gives me an error.

Abdullah Mujahid
  • 888
  • 1
  • 12
  • 34

1 Answers1

0

If I'm understanding right, you're trying to insert the current user's ID into the commentLikes array when the current user likes a comment.

See Mongo push to array inside array. Your current code is going to push a new items into comments. You should use update here so you can specify more than one search criteria. This will let you find the element in the comments, but you'll need the comment ID as well as the post ID (otherwise, how are you planning to find the right item from the comments array if more than one are present?)

Post.update(
    {"_id" : req.body.postId, "comments._id": '{the ID of the comment that was liked}',
    {$push:{"comments.$.commentLikes": req._user.id}}
)

This will find the post with the specified ID, find the correct commend depending on who originally posted it, and add the current user's ID to the commentLikes list. However, like the linked answer states, this is a pretty messy way to handle this and it would likely be better to have a separate collection of comments with an ID pointing back to the post. Arrays inside of arrays get complicated very fast.

Joseph
  • 865
  • 5
  • 20
  • I have managed to get comment id from client to server, yes you were right I forgot to pass comment id from frontend. – Abdullah Mujahid Apr 13 '21 at 05:48
  • Now Post.findByIdAndUpdate(req.params.comment_id, { $push: { "comments.$commentLikes": req.user._id } }, { new: true }).exec((err, result) => { if (err) { return res.status(422).json({ error: err }) } else { console.log(result) res.json(result) } }) – Abdullah Mujahid Apr 13 '21 at 05:52
  • it is returniing me NULL can you help me out in this. I am getting comment id – Abdullah Mujahid Apr 13 '21 at 05:52
  • Did you figure it out? If you need to get the element you're inserting as well as update it, you can use findAndUpdate, but you can't use findByIdAndUpdate because you need a more complicated filter than just an ID. – Joseph Apr 14 '21 at 00:26
  • No i couldn't figured out, actually I am using findByIdAndUpdate to delete comment and I placed commentLikes outside the comments it was working but when I like 1 comment it updates the other one as well. The only problem I am facing is just accessing the commentLikes when it is inside comments. – Abdullah Mujahid Apr 15 '21 at 05:44