skip to Main Content

So, i have been trying to make a function that deletes reviews and it just isn’t working. I narrowed it down, and it seems that the filter is not working correctly, couldn’t figure out why. Please check the code and tell me what to do:

//Delete review
exports.deleteReview=catchAsyncErrors(async(req,res,next)=>{
    //Find product by its Id
    const product=await Product.findById(req.query.productId);
    const reviewId=req.query.id.toString()

    if(!product){
        return next(new ErrorHandler("Product not Found!",400))
    }
    console.log('Review ID (from query):', reviewId);
    console.log('Existing reviews:', product.reviews);

    //Filter out the reviews by its _id
    const updatedReviews = product.reviews.filter(rev => {
        console.log('Review ID:', rev._id.toString(), '==', reviewId);
        return rev._id.toString() !== reviewId;
    });
    console.log('Updated reviews:', updatedReviews);

    //if the filter didn't work or invalid id

    if (updatedReviews.length === product.reviews.length) {
        return next(new ErrorHandler("Review not found. Invalid review ID", 400));
    }

    //Calculate the rating and new numofReviews
    let avg=0;
    if (updatedReviews.length > 0) {
        updatedReviews.forEach(rev => {
            avg += rev.rating;
        });
        avg /= updatedReviews.length;
    }

    //Update the product with new reviews,ratings and numOfReviews
    const updatedProduct=await Product.findByIdAndUpdate(req.query.productId,{
        reviews:updatedReviews,
        ratings:avg,
        numofReviews:updatedReviews.length
    },{
        new:true,
        runValidators:true,
        useFindAndModify:false
    })

    await product.save()

    res.status(200).json({
        success:true,
        updatedProduct
    })

})

//Route
//Delete a review
router.route("/review").delete(isAuthenticatedUser,deleteReview)

Below is the database —

{
  "_id": {
    "$oid": "6686669d001eaace2f3cc103"
  },
  "name": "Product256",
  "description": "MSI Katana",
  "price": 200000,
  "ratings": 4.5,
  "images": [
    {
      "public_id": "Image abcde",
      "url": "SampleImageURI",
      "_id": {
        "$oid": "6686669d001eaace2f3cc104"
      }
    }
  ],
  "category": "Laptop",
  "stock": 3,
  "numofReviews": 2,
  "user": {
    "$oid": "6680fe296f7960665677f468"
  },
  "reviews": [
    {
      "user": {
        "$oid": "6680fe296f7960665677f468"
      },
      "name": "Someone1",
      "rating": 5,
      "comment": "Excellent!",
      "_id": {
        "$oid": "668684131c5010baf9c1fdf3"
      }
    },
    {
      "user": {
        "$oid": "668168d89de2122e5c13c8a9"
      },
      "name": "Someone2",
      "rating": 4,
      "comment": "uhfvkuh!",
      "_id": {
        "$oid": "6686842f1c5010baf9c1fdfa"
      }
    }
  ],
  "createdAt": {
    "$date": "2024-07-04T09:08:45.192Z"
  },
  "__v": 4
}

As you can see i tried debugging using a lot of console.log and well here is a result–
//Result

[nodemon] restarting due to changes...
[nodemon] starting `node Backend/server.js`
Server is working on http://localhost:4000
MongoDb connected with server: 127.0.0.1
Review ID (from query): 6686842f1c5010baf9c1fdfa

Existing reviews: [
  {
    user: new ObjectId('6680fe296f7960665677f468'),
    name: 'Someone1',
    rating: 5,
    comment: 'Excellent!',
    _id: new ObjectId('668684131c5010baf9c1fdf3')
  },
  {
    user: new ObjectId('668168d89de2122e5c13c8a9'),
    name: 'Someone2',
    rating: 5,
    comment: 'Remove this!',
    _id: new ObjectId('6686842f1c5010baf9c1fdfa')
  }
]
Review ID: 668684131c5010baf9c1fdf3 == 6686842f1c5010baf9c1fdfa

Review ID: 6686842f1c5010baf9c1fdfa == 6686842f1c5010baf9c1fdfa

Updated reviews: [
  {
    user: new ObjectId('6680fe296f7960665677f468'),
    name: 'Someone1',
    rating: 5,
    comment: 'Excellent!',
    _id: new ObjectId('668684131c5010baf9c1fdf3')
  },
  {
    user: new ObjectId('668168d89de2122e5c13c8a9'),
    name: 'Someone2',
    rating: 5,
    comment: 'Remove this!',
    _id: new ObjectId('6686842f1c5010baf9c1fdfa')
  }
]

The postman is giving the result without removing the review.

2

Answers


  1. Chosen as BEST ANSWER

    Turns out there was extra whitespace in reviewId used .trim() in filter and it worked. Thanks -VLAZ


  2. The problem lies in how the _id is structured within each review. Specifically, the _id field is nested within an object with the key $oid.

    Here is sample code to fix that

    const product = {
      "_id": {
        "$oid": "6686669d001eaace2f3cc103"
      },
      "name": "Product256",
      "description": "MSI Katana",
      "price": 200000,
      "ratings": 4.5,
      "images": [
        {
          "public_id": "Image abcde",
          "url": "SampleImageURI",
          "_id": {
            "$oid": "6686669d001eaace2f3cc104"
          }
        }
      ],
      "category": "Laptop",
      "stock": 3,
      "numofReviews": 2,
      "user": {
        "$oid": "6680fe296f7960665677f468"
      },
      "reviews": [
        {
          "user": {
            "$oid": "6680fe296f7960665677f468"
          },
          "name": "Someone1",
          "rating": 5,
          "comment": "Excellent!",
          "_id": {
            "$oid": "668684131c5010baf9c1fdf3"
          }
        },
        {
          "user": {
            "$oid": "668168d89de2122e5c13c8a9"
          },
          "name": "Someone2",
          "rating": 4,
          "comment": "uhfvkuh!",
          "_id": {
            "$oid": "6686842f1c5010baf9c1fdfa"
          }
        }
      ],
      "createdAt": {
        "$date": "2024-07-04T09:08:45.192Z"
      },
      "__v": 4
    };
    
    const reviewId = '6686842f1c5010baf9c1fdfa';  // Ensure reviewId is a string
    // Here is the fix
    const updatedReviews = product.reviews.filter(rev => {
        const reviewOid = rev._id.$oid;  // Access the $oid property
        console.log('Review ID:', reviewOid, '==', reviewId);
        return reviewOid !== reviewId;
    });
    
    console.log('Updated Reviews:', updatedReviews);
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search