Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Mongoose returns empty object instantiated with req.body

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!

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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>

>Solution :

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}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading