Home > Net >  Mongoose returns empty object instantiated with req.body
Mongoose returns empty object instantiated with req.body

Time:01-02

Good day!

Invoice model has nested Item array and I'm instantiating new Item object with req.body from newItem.ejs but Mongoose is returning empty object even though req.body is not empty.

Any advice would be appreciated!

index.js

const express = require('express');
const app = express();
const path = require('path');
const mongoose = require('mongoose');
const Invoice = require('./model/invoice');
const Item = require('./model/invoice');
const bodyParser = require('body-parser')

app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: true }))
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');

app.post('/invoice/:id/newItem', (req, res) => {
    const { id }  = req.params;
    const newItem = new Item(req.body);

    console.log(req.body); // returns {barcode: '666666', vendorRef: 'test', name: 'test', color: 'test' size: '6', cost: '6', quantity: '6'}

    console.log(newItem); // returns { _id: new ObjectId("61d18085424a77e2159b4e38"), items: [] }

    Invoice.findByIdAndUpdate(
        {_id: id},
        {$push: { items: newItem}}).
        then(() => {
            console.log("Item Added")
        })
        .catch((err) => {
            console.log('Error');
            console.log(err);
        })
    res.redirect(`/search/${id}`);
})

The comments above show that the req.body is not empty but the object is returning only with id.

Model

const mongoose = require('mongoose');

const itemSchema = new mongoose.Schema({
    barcode: Number,
    vendorRef: String,
    name: String,
    color: String,
    size: Number,
    cost: Number,
    quantity: Number
})

const invoiceSchema = new mongoose.Schema({
    invoiceNumber: {
        type: Number,
        required: true
    },
    invoiceDate: {
        type: Date,
        required: true
    },
    vendor: {
        type: String,
        required: true
    },
    store: {
        type: String,
        required: true
    },
    onDelivery: Boolean,
    deliveryDate: Date,
    received: Boolean,
    receivedDate: Date,
    posUpdated: Boolean,
    posUpdatedDate: Date,
    items: [itemSchema]
})

const Item = mongoose.model('Item', itemSchema);
const Invoice = mongoose.model('Invoice', invoiceSchema);

module.exports = Item;
module.exports = Invoice;

newItem.ejs

    <form action="/invoice/<%= invoice._id %>/newItem" method="post">

        <label for="barcode">Barcode</label>
        <input type="number" id="barcode" name="barcode"> <br>

        <label for="vendorRef">VendorRef</label>
        <input type="text" id="vendorRef" name="vendorRef"> <br>

        <label for="name">Name</label>
        <input type="text" id="name" name="name"> <br>
    
        <label for="color">Color</label>
        <input type="text" id="color" name="color"> <br>

        <label for="size">Size</label>
        <input type="number" id="size" name="size"> <br>

        <label for="cost">Cost</label>
        <input type="number" id="cost" name="cost"> <br>

        <label for="quantity">Quantity</label>
        <input type="number" id="quantity" name="quantity"> <br>
        
        <button>Add</button>
    </form>

CodePudding user response:

The way you have exported the values from the invoice.js file is not correct. You are reassigning the value of module.exports to Invoice which is why only that schema is being exported.

Therefore you have imported the wrong model into Item. You could either separate the Item schema into its own file which would structure things better ie. move the code for the Item schema into item.js

// file: models/item.js
const mongoose = require('mongoose');

const itemSchema = new mongoose.Schema({
    barcode: Number,
    vendorRef: String,
    name: String,
    color: String,
    size: Number,
    cost: Number,
    quantity: Number
});

const Item = mongoose.model('Item', itemSchema);

module.exports = {Item, itemSchema};

// file: models/invoice.js
const mongoose = require('mongoose');
const {itemSchema} = require("./item.js");
 
const invoiceSchema = new mongoose.Schema({
    invoiceNumber: {
        type: Number,
        required: true
    },
    invoiceDate: {
        type: Date,
        required: true
    },
    vendor: {
        type: String,
        required: true
    },
    store: {
        type: String,
        required: true
    },
    onDelivery: Boolean,
    deliveryDate: Date,
    received: Boolean,
    receivedDate: Date,
    posUpdated: Boolean,
    posUpdatedDate: Date,
    items: [itemSchema]
})

const Invoice = mongoose.model('Invoice', invoiceSchema);

module.exports = {Invoice, invoiceSchema};

// file: index.js
const { Invoice } = require('./model/invoice');
const { Item } = require('./model/item');

OR

You could destructure the schemas from the same file in a single line

const express = require('express');
const app = express();
const path = require('path');
const mongoose = require('mongoose');
const { Invoice, Item }= require('./model/invoice'); // This line
// const = require('./model/invoice');// Get rid of this
const bodyParser = require('body-parser')

to do this you would also have to change the exports line in invoice.js to

module.exports = {Item, Invoice}
  • Related