Home > Software engineering >  Subdocument not being saved in its own collection - Mongoose
Subdocument not being saved in its own collection - Mongoose

Time:05-13

I found this on the documentation for mongoose:

Subdocuments have save and validate middleware just like top-level documents. Calling save() on the parent document triggers the save() middleware for all its subdocuments, and the same for validate() middleware.

But that hasn't been working for me. when I call save on my parent, the subdocument doesn't get created in its own collection. Here's my code:

Cart Model

const mongoose = require("mongoose");

const cartSchema = new mongoose.Schema({
    numOfSessions: {
        type: Number,
        required: true
    },
    status:{
        type: String,
        enum: ["completed", "active", "deleted"],
        required: true
    }
    
}, { timestamps: true, versionKey: false });

const Cart = mongoose.model('shoppingCart', cartSchema);
module.exports = Cart;

User Model

const mongoose = require("mongoose");
const Cart = require("./xxxx").schema
const Schema = mongoose.Schema;


const userSchema = new Schema({
    firstName: {
        type: String,
        required: true
    },
    lastName: {
        type: String,
        required: true
    },
    password: {
        type: String,
        required: true,
    },
    email: {
        type: String,
        required: true,
        unique: true
    },
    shoppingCarts: [ Cart ]
}, { timestamps: true, versionKey: false });

const User = mongoose.model('user', userSchema);
module.exports = User;

Server Side

const new_user = new User({
                firstName: req.body.firstname,
                lastName: req.body.lastname,
                username: req.body.username,
                phoneNum: req.body.phone,
                userType: req.body.userType,
                email: req.body.email,
                password: hashedPassword
            });

            new_user.shoppingCarts.push(new_cart);
            console.log('pushed')
            new_cart.save(); //If i take out this line, this subdocument doesn't get saved
            new_user.save()
                .then((result) => {
                    console.log(result);
 });

To save the subdocument, I'm having to call save on it them well. Is this how it's supposed to be? Thx :D

CodePudding user response:

Looking at the docs, I think it should be added this way. give this a try.

const new_user = new User({
                firstName: req.body.firstname,
                lastName: req.body.lastname,
                username: req.body.username,
                phoneNum: req.body.phone,
                userType: req.body.userType,
                email: req.body.email,
                password: hashedPassword,
                shoppingCarts:[new_cart]
            });

CodePudding user response:

To create a reference to the Cart schema you should declare the shoppingCarts property as ObjectId in your userSchema:

const mongoose = require('mongoose');
const Cart = require('./xxxx').schema;
const Schema = mongoose.Schema;

const userSchema = new Schema(
  {
    ...
    shoppingCarts: [{
        type: mongoose.Types.ObjectId,
        ref: 'shoppingCart'
    }],
  },
  { timestamps: true, versionKey: false }
);

const User = mongoose.model('user', userSchema);

module.exports = User;

You should then be able to create your new_user with:

const new_user = await User.create({
  firstName: req.body.firstname,
  lastName: req.body.lastname,
  username: req.body.username,
  phoneNum: req.body.phone,
  userType: req.body.userType,
  email: req.body.email,
  password: hashedPassword,
});
// Push the `id` of the cart
new_user.shoppingCarts.push(new_cart._id);
// Save the updated user
await new_cart.save(); 

To retrieve a User instance you will then need to populate its shoppingCart ref with:

const user = await User.find({}).populate('shoppingCarts').exec()
  • Related