Aquí está mi esquema de mangosta:
var mongoose = require('mongoose'); var Schema = mongoose.Schema; var CartSchema = new Schema({ userID: String, items: [{ itemID: String, quantity: Number }] }); module.exports = mongoose.model('Cart', CartSchema); Aquí está el servidor node.js que usa Express. Tiene una ruta /add-to-cart que, si se activa, debería actualizar el carrito del usuario con la información pasada en req.body:
router.post('/add-to-cart', function(req, res, next) { Cart.find({ userID: req.body.userID }).then(function(userCart){ console.log("TEST: "+JSON.stringify(userCart)); var myItem = {itemID: req.body.itemId, quantity: 1} userCart.items.push(myItem); res.send(userCart); }).catch(next); });Imprimí en el terminal userCart como puede ver en mi código y me devolvió esto:
[{ "_id":"58f7368b42987d4a46314421", // cart id "userID":"58f7368a42987d4a46314420", // userid "__v":0, "items":[] }] Cuando el servidor ejecuta userCart.items.push(myItem); devuelve este error:
Cannot read property 'push' of undefined ¿Por qué items no están definidos si ya he definido su estructura en mangosta?
Como adeneo señaló correctamente, userCart es claramente una matriz, pero debe usar uno de los métodos de actualización para enviar el documento a la matriz de elementos, sugeriría Model.findOneAndUpdate() como en
router.post('/add-to-cart', function(req, res, next) { Cart.findOneAndUpdate( { userID: req.body.userID }, { $push: { items: { itemID: req.body.itemId, quantity: 1 } } }, { new: true } ) .exec() .then(function(userCart) { console.log("TEST: "+ JSON.stringify(userCart)); res.send(userCart); }) .catch(next); });Como adeneo señaló, userCart es una matriz ya que está utilizando el método de búsqueda. Pero claramente necesita encontrar solo un documento dado por su ID de usuario, por lo que se recomienda usar findOne() en su lugar.
También deberá guardar el documento para que los cambios se reflejen realmente.
Eche un vistazo al código actualizado a continuación:
router.post('/add-to-cart', function(req, res, next) { Cart.findOne({ userId: req.body.userID }, function(err, userCart){ if(err) return next(err); console.log("TEST: "+JSON.stringify(userCart)); var myItem = {itemID: req.body.itemId, quantity: 1} userCart.items.push(myItem); userCart.save(function(err, usersCart) { if(err) return next(err); res.send(usersCart); }) }) });Espero que esto haya ayudado.
Esto se puede resolver usando:
router.post('/add-to-cart', function(req, res, next) { Cart.findOne({ userID: req.body.userID }).then(function(userCart){ console.log("TEST: "+JSON.stringify(userCart)); const a = req.body.items; for(i=0;i<a.length;i++) { userCart.items.push(req.body.items[i]); } res.send(userCart); }).catch(next); });