所以,问题是我正在尝试添加相关产品的评论。但每当我尝试通过 Postman 访问 API 时,都会出现错误
ValidationError: Product validation failed: rating: Cast to Number failed for value "NaN" (type number) at path "rating"
[0] at Document.invalidate (E:\Web\Shop.co\node_modules\mongoose\lib\document.js:3197:32)
[0] at model.$set (E:\Web\Shop.co\node_modules\mongoose\lib\document.js:1456:12)
[0] at model.set [as rating] (E:\Web\Shop.co\node_modules\mongoose\lib\helpers\document\compile.js:205:19)
[0] at E:\Web\Shop.co\backend\controller\productController.js:108:20
[0] at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
这是产品架构
const mongoose = require("mongoose");
const reviewSchema = mongoose.Schema(
{
name: { type: String, required: true },
rating: { type: Number, required: true, default: 0 },
comment: { type: String, required: true },
user: {
type: mongoose.Schema.Types.ObjectId,
required: true,
ref: "User",
},
},
{
timestamps: true,
}
);
const productSchema = mongoose.Schema(
{
user: {
type: mongoose.Schema.Types.ObjectId,
required: true,
ref: "User",
},
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,
},
price: {
type: Number,
required: true,
default: 0,
},
review: [reviewSchema],
rating: {
type: Number,
required: true,
default: 0,
},
numReviews: {
type: Number,
required: true,
default: 0,
},
countInStock: {
type: Number,
required: true,
default: 0,
},
},
{
timestamps: true,
}
);
const Product = mongoose.model("Product", productSchema);
module.exports = Product;
这是产品控制器中的 createReview 函数
const createReview = asyncHandler(async (req, res) => {
const { rating, comment } = req.body;
const product = await Product.findById(req.params.id);
if (product) {
const alreadyReviewed = product.review.find(
(r) => r.user.toString() === req.user._id.toString()
);
if (alreadyReviewed) {
res.status(400).json({ message: " Product already reviewed" });
throw new Error("Product already reviewed");
}
const reviews = {
name: req.user.name,
rating: Number(rating),
comment,
user: req.user._id,
};
product.review.push(reviews);
product.numReviews = product.review.length;
product.rating =
product.review.reduce((item, acc) => item.rating + acc, 0) /
product.review.length;
await product.save();
res.status(100).json({ message: " Review Added" });
} else {
res.status(400).json({ message: " Product not found" });
throw new Error("Product not found");
}
});
路线是
router.route("/:id/reviews").post(protect, createReview);
虽然评分被定义为 Number 类型并在创建评论时给定 Number,但它仍然给出 NaN 错误。
如果我错了或者我的代码错误,请给我建议,先谢谢你!
发生错误是因为reduce函数没有正确总结评论的评分。
要解决此问题,您需要通过正确总结所有评论的评分来调整产品评分的计算。这是 createReview 函数的更正版本
const createReview = asyncHandler(async (req, res) => {
const { rating, comment } = req.body;
const product = await Product.findById(req.params.id);
if (product) {
const alreadyReviewed = product.review.find(
(r) => r.user.toString() === req.user._id.toString()
);
if (alreadyReviewed) {
res.status(400).json({ message: "Product already reviewed" });
throw new Error("Product already reviewed");
}
const review = {
name: req.user.name,
rating: Number(rating),
comment,
user: req.user._id,
};
product.review.push(review);
product.numReviews = product.review.length;
// Calculate new average rating
const totalRating = product.review.reduce((acc, item) => acc + item.rating, 0);
product.rating = totalRating / product.review.length;
await product.save();
res.status(200).json({ message: "Review Added" });
} else {
res.status(404).json({ message: "Product not found" });
throw new Error("Product not found");
}
});