Today I going to talk about a very important concept but maybe a little bit hard to understand. Let's dive in.

We can add our own methods and logic to model Schema. For example, take this user Schema.

const userSchema = new Schema({
  name: {
    type: String,
    required: true,
  },

  email: {
    type: String,
    required: true,
  },
  cart: {
    items: [
      {
        productId: { type: Schema.Types.ObjectId, ref: "Product" },
        quantity: { type: Number, required: true },
      },
    ],
  },
});


Let’s write a function to add a shopping cart.

userSchema.methods.addToCart = function () {

    //we can add a custom logic in here
}

module.exports = mongoose.model("User", userSchema);




Example function

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(); // built in save method
};


//simple clear a shopping cart

userSchema.methods.clearCart = function () {
  this.cart = { items: [] };
  return this.save();
};


Bonus

Previously we discussed how to get some field values using populate().
Today -> Getting the hole document


exports.postOrder = (req, res, next) => {
  req.user
    .populate("cart.items.productId")
    .execPopulate()
    .then((user) => {
      const products = user.cart.items.map((i) => {
        return { quantity: i.quantity, productData: { ...i.productId._doc } };
        /*     
                look here -> taking the product id and call its entire doc  &
                stored entire document in the products data field
        */
      });
      const order = new Order({
        user: {
          name: req.user.name,
          userId: req.user,
        },
        products: products,
      });
      return order.save();
    })

    .then((result) => {
      res.redirect("/orders");
    })
    .catch((err) => {
      console.log(err);
    });
};