req.user.populate不是函数报错排查:购物车关联商品数据需求
问题描述
我正在开发电商网站的购物车功能,期望进入购物车页面时,展示用户购物车中所有商品的详细信息及对应数量。我的User模型包含cart字段,其items数组存储productId和quantity字段。但在shop控制器的getCart方法中调用req.user.populate('cart.items.productId').execPopulate()时,出现了「req.user.populate(...) IS NOT A FUNCTION」的错误。已尝试更新Mongoose等操作,仍未解决问题。
相关代码
app.js
const path = require('path'); const express = require('express'); const bodyParser = require('body-parser'); const mongoose = require('mongoose'); const errorController = require('./controllers/error'); const User = require('./models/user'); const app = express(); app.set('view engine', 'ejs'); app.set('views', 'views'); const adminRoutes = require('./routes/admin'); const shopRoutes = require('./routes/shop'); app.use(bodyParser.urlencoded({ extended: false })); app.use(express.static(path.join(__dirname, 'public'))); app.use((req,res,next)=>{ User.findById('657167533934e81f519f9bbd') .then(user=>{ req.user = user; next(); }) .catch(err=>{ console.log(err) }) }) app.use('/admin', adminRoutes); app.use(shopRoutes); app.use(errorController.get404); mongoose.connect('mongodb+srv://feri:Bardia2323@cluster0.acwxu0j.mongodb.net/shop?retryWrites=true&w=majority') .then(result=>{ User.findOne().then(user =>{ if(!user){ const user = new User({ name:'feri', email:'feriorse@gmail.com', cart:{ items:[] } }); user.save(); } }); app.listen(3000); }).catch(err=>{ console.log(err); })
shop控制器
exports.getCart = (req, res, next) => { req.user .populate('cart.items.productId') .execPopulate() .then(user => { const products = user.cart.items; console.log(products); res.render('shop/cart', { path: '/cart', pageTitle: 'Your Cart', products: products }) }) .catch(err => console.log(err)); };
User模型
const mongoose = require('mongoose'); const Schema = mongoose.Schema; const userSchema = new Schema({ name:{ type: String, required:true }, email:{ type:String, required: true }, cart:{ items:[{productId:{type:Schema.Types.ObjectId,ref:'Product',required:true}, quantity:{type:Number,required:true}}] } }); userSchema.methods.addToCart = function (product){ const cartProductIndex = this.cart.items.findIndex(cp=>{ return cp.productId.toString() === product._id.toString(); }); let newQuantity = 1; const updatedCartItems = [...this.cart.items]; if(cartProductIndex>=0){ newQuantity = this.cart.items[cartProductIndex].quantity + 1; updatedCartItems[cartProductIndex].quantity = newQuantity } else{ updatedCartItems.push({productId:product._id,quantity:newQuantity}) } const updatedCart = {items:updatedCartItems}; this.cart = updatedCart; return this.save(); } module.exports = mongoose.model('User',userSchema);
Product模型
const mongoose = require('mongoose'); const Schema = mongoose.Schema; const productSchema = new Schema({ title: { type:String, required: true }, price:{ type: Number, required:true }, description:{ type: String, required: true }, imageUrl:{ type:String, required:true }, userId:{ type:Schema.Types.ObjectId, ref:'User', required:true, } }) module.exports = mongoose.model('Product',productSchema);
解决方案
这个错误的核心原因是Mongoose 6.x及以上版本已移除execPopulate()方法,且文档实例的populate()方法直接返回Promise,无需再链式调用execPopulate()。
修改shop控制器的getCart方法即可解决:
exports.getCart = (req, res, next) => { req.user .populate('cart.items.productId') .then(user => { const products = user.cart.items; console.log(products); res.render('shop/cart', { path: '/cart', pageTitle: 'Your Cart', products: products }); }) .catch(err => console.log(err)); };
如果偏好更简洁的写法,也可以用async/await:
exports.getCart = async (req, res, next) => { try { const user = await req.user.populate('cart.items.productId'); const products = user.cart.items; console.log(products); res.render('shop/cart', { path: '/cart', pageTitle: 'Your Cart', products: products }); } catch (err) { console.log(err); } };
额外验证点
- 确认Mongoose版本:执行
npm list mongoose查看版本,确保是6.x+,上述修改才适用。 - 检查User模型关联:确认
cart.items.productId的ref属性已正确指向Product模型(你的代码中已正确设置,无需修改)。
内容的提问来源于stack exchange,提问作者bardia
相关产品推荐
相关产品推荐

