Home > Software design >  How to update and delete a review of a product using nodejs
How to update and delete a review of a product using nodejs

Time:05-04

I am creating a e-commerce app and now I want to update and delete a review of a product using nodejs and database is mongoDB (using mongoose). This is my User Schemas and Product Schema:

const userSchema = new Schema(
  {
    name: { type: String, required: true },
    email: { type: String, required: true, unique: true, trim: true },
    password: { type: String, required: true, trim: true },
    isAdmin: { type: Boolean, required: true, default: false },
  },
  {
    timestamps: true,
  }
);

const productSchema = new Schema({
  user: {
    type: Schema.Types.ObjectId,
    required: true,
    ref: "users",
  },
  name: { type: String, required: true },
  image: { type: String, required: true },
  brand: { type: String, required: true },
  category: { type: String, required: true },
  description: { type: String, required: true },
  reviews: [
    {
      name: { type: String, required: true },
      rating: { type: Number, required: true },
      comment: { type: String, required: true },
      user: {
        type: Schema.Types.ObjectId,
        required: true,
        ref: "users",
      },
    },
    {
      timestamps: true,
    },
  ],
  rating: { type: Number, required: true, default: 0 },
  reviewNumber: { type: Number, required: true, default: 0 },
  price: { type: Number, required: true, default: 0 },
  countInStock: { type: Number, required: true, default: 0 },
});

I completed the create function but I don't know how to implement update and delete function, this this my create function:

//* desc   Create review
//* route  POST /product/:id/review
//* access Private
const createReview = async (req, res) => {
  const { rating, comment } = req.body;

  if (!rating || !comment) {
    return res.status(400).json({
      success: false,
      message: "Missing infomation",
    });
  }

  try {
    const product = await Product.findById(req.params.id);

    if (!product) {
      return res.status(400).json({
        success: false,
        message: "Product is not found",
      });
    }

    const review = product.reviews;

    const alreadyReviewed = product.reviews.find(
      (i) => i.user.toString() === req.user._id.toString()
    );

    if (alreadyReviewed) {
      return res.status(400).json({
        success: false,
        message: "User have already reviewed this product",
      });
    }

    const newReview = {
      name: req.user.name,
      rating: 0 || Number(rating),
      comment,
      user: req.user._id,
    };

    review.push(newReview);
    product.reviewNumber = review.length;
    product.rating =
      review.reduce((acc, item) => item.rating   acc, 0) / review.length;

    await product.save();

    return res.status(200).json({
      success: true,
      message: "Create review successfully",
      product,
    });
  } catch (error) {
    console.log(error);
    return res.status(500).json({
      success: false,
      message: "Internal server error",
    });
  }
};

So how can I implement update and delete function?

CodePudding user response:

I am assuming according to your code one product can have only one review per user.

//* desc update review
//* route  PUT /product/:id/review
//* access Private
const createReview = async (req, res) => {
  const { rating, comment  } = req.body;

  if (!rating || !comment) {
    return res.status(400).json({
      success: false,
      message: "Missing infomation",
    });
  }

  try {
    const product = await Product.findById(req.params.id);

    if (!product) {
      return res.status(400).json({
        success: false,
        message: "Product is not found",
      });
    }

    const reviews = product.reviews;
    
    const foundReviewIndex = product.reviews.findIndex(
      (i) => i.user.toString() === req.user._id.toString()
    );

    if (foundReviewIndex === -1) {
      return res.status(400).json({
        success: false,
        message: "Review not found",
      });
    }

    reviews[foundReviewIndex].rating = rating ? Number(rating) : 0,
    reviews[foundReviewIndex].comment = comment,

    product.rating =
      review.reduce((acc, item) => item.rating   acc, 0) / review.length;

    await product.save();

    return res.status(200).json({
      success: true,
      message: "Updated review successfully",
      product,
    });
  } catch (error) {
    console.log(error);
    return res.status(500).json({
      success: false,
      message: "Internal server error",
    });
  }
};

Similarly, you can write a function for deleting a review. I suggest you create a separate collection for reviews and keep both product and user references in the review schema.

CodePudding user response:

I've created a sample route. Obviously you can change the route acc. to your needs, and pass in the necessary parameters.

I've used $pull operator to delete the review from a product using userId

app.delete("/deleteReview/:productId/:userId", async (req, res) => {
  try {
    // userId could also be from your middleware so you can change it here.
    
    const { productId, userId } = req.params;
    const product = await ProductModel.findOneAndUpdate(
      { _id: productId },
      { $pull: { reviews: { user: userId } } },
      { new: true }
    );

    res.json(product);
  } catch (error) {
    console.error(error);
    return res.status(500).send(`Server error`);
  }
});

Regarding updating review, I want to know whether you're going to update review using reviewId or userId? I'll update the answer acc. to your answer.

  • Related