Search code examples
node.jspostmodelschemaexpress-session

Model returns undefined property in post route but not get route


In my static file:

    <form action="/confirm-purchase" method="post">
                <input type="text" id="name" class="form-control" required name="name">
                <input type="text" id="address" class="form-control" required name="address">
        <input type="submit" value="Send Order" class="btn btn-success">
    </form>

When Send Order is clicked, the code should get data such as the user object and cart model and place them in the model order and save them to the database.

However when I click Send Order an error on the page appears saying it cannot read the property 'cart' of undefined and that the error comes from the line where I declared the variable cart within the post route. The same variable was in the get route and that somehow caused no problems.

What did I do wrong?

In my routes:

// get
router.get("/confirm-purchase", (req, res, next) => {
  if (!req.session.cart) {
    return res.render("shop/confirm-purchase", {products: null});
  }
  var cart = new Cart(req.session.cart);
  res.render("shop/confirm-purchase", {totalPrice: cart.totalPrice});
});

// post
router.post("/confirm-purchase", (res, req, next) => {
  var cart = new Cart(req.session.cart);
  if(!req.session.cart) {
    return res.redirect("/shopping-cart");
  }
  var order = new Order({
    user: req.user, //user is object placed by passport.js
    cart: cart,
    name: req.body.name,
    address: req.body.address
  });
  order.save(() => {
    req.flash("success", "Successfully bought product/s!");
    req.session.cart = null;
    res.redirect("/");
  });
});

My cart model:

module.exports = function Cart(oldCart) {
    this.items = oldCart.items || {};
    this.totalQty = oldCart.totalQty || 0;
    this.totalPrice = oldCart.totalPrice || 0;

    this.add = function(item, id) {
      var storedItem = this.items[id];
      if (!storedItem) {
          storedItem = this.items[id] = {item: item, qty: 0, price: 0};
      }
      storedItem.qty++;
      storedItem.price = storedItem.item.price * storedItem.qty;
      this.totalQty++;
      this.totalPrice += storedItem.item.price;
    }

    this.generateArray = function() {
        var arr = [];
        for (var id in this.items) {
            arr.push(this.items[id]);
        }
        return arr;
    }
  };

My order model:

var mongoose = require("mongoose");
var Schema = mongoose.Schema;

var schema = new Schema({
    user: {type: Schema.Types.ObjectId, ref: "User"},
    cart: {type: Object, required: true},
    address: {type: String, required: true},
    name: {type: String, required: true}
});

module.exports = mongoose.model("orderSchema", schema);

Solution

  • I finally worked it out: The res and req parameters in the get and post routes are in written in different orders.

    My old code:

    // get
    router.get("/confirm-purchase", (req, res, next) => {/*...*/}
    
    // post
    router.post("/confirm-purchase", (res, req, next) => {/*...*/}
    

    Should be:

    // get
    router.get("/confirm-purchase", (req, res, next) => {/*...*/}
    
    // post
    router.post("/confirm-purchase", (req, res, next) => {/*...*/}