Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
132 views
in Technique[技术] by (71.8m points)

node.js - Mongoose - Cannot modify field value

I am building a simple shop backend for practice purposes. I have three schemas Product, Customer and Order.

What I am trying to achieve is to subtract the ordered quantity from the stock quantity for each product inside an order, when the order is created. Clearly I am doing something wrong cause my productsToUpdateInDbArray contains the correct products (checked it with console log) but I can't find a way to make it work.

stockQty field inside Products collection is not updating.

My controller code is:

'use strict'

// require validator for string validation
const validator = require('validator');
// import Order, Customer, Product Models
const Order = require("../models/order.model");
const Customer = require("../models/customer.model");
const Product = require("../models/product.model");

// DEFINE CONTROLLER FUNCTIONS

// listAllOrders function - To list all orders
exports.listAllOrders = (req, res) => {
    Order.find({}, (err, orders) => {
        if (err) {
            return res.status(500).send(`Internal server error: ${error}`);
        }

        if (orders && orders.length === 0) {
            return res.status(404).send(`No orders found!`);
        }

        return res.status(200).json(orders);
    });
};

// createNewOrder function - To create new order
exports.createNewOrder = (req, res) => {
    const customerId = req.body?.customerId;
    const productsArray = req.body?.products;

    let productsToUpdateInDbArray = [];

    if (!validator.isMongoId(customerId)) {
        return res.status(400).send('Invalid customer Id');
    }

    Customer.findById(customerId, async (err, customer) => {
        if (err) {
            return res.status(500).send(`Internal server error: ${error}`);
        }

        if (!customer) {
            return res.status(404).send(`No customers found!`);
        }

        if (!productsArray || productsArray.length === 0) {
            return res.status(400).send(`No products found in the order!`);
        }

        for (let product of productsArray) {
            if (!validator.isMongoId(product?.productId)) {
                return res.status(400).send('Invalid product Id');
            }

            if (!product?.quantity || product?.quantity < 1) {
                return res.status(400).send('Invalid product quantity');
            }

            let productFound = await Product.findById(product?.productId).exec();
            
            if (!productFound) {
                return res.status(404).send('Product not found!');
            }

            if (productFound.stockQty < product.quantity) {
                return res.status(400).send('Not enough product quantity in stock')
            }

            productFound.stockQty -= product.quantity;
            productsToUpdateInDbArray.push(productFound);
        }

        console.log(productsToUpdateInDbArray)

        const newOrder = new Order(req.body);
        newOrder.save((err, order) => {
            if (err) {
                return res.status(500).send(`Internal server error: ${error}`);
            }

            for (let item of productsToUpdateInDbArray) {
                const filter = { _id: item._id };
                const update = { stockQty: item.stockQty };

                Product.findOneAndUpdate( filter, update )
            }
            return res.status(201).json(order);
        });
    });
};


And my models are:

'use strict';

// Import mongoose
const mongoose = require("mongoose");

// Declare schema and assign Schema class
const Schema = mongoose.Schema;

// Create Schema Instance and add schema propertise
const ProductSchema = new Schema({
    name: {
        type: String,
        required: true
    },
    price: {
        type: Number,
        required: true
    },
    description: {
        type: String,
        required: true
    },
    imageUrl: {
        type: String,
        required: true
    },
    stockQty: {
        type: Number,
        required: true
    }
});

// create and export model
module.exports = mongoose.model("Products", ProductSchema);
'use strict';

// Import mongoose
const mongoose = require("mongoose");

// Declare schema and assign Schema class
const Schema = mongoose.Schema;

// Create Schema Instance and add schema propertise
const OrderSchema = new Schema({
    products: [
        {
            productId: {
                type: Schema.Types.ObjectId,
                required: true,
                ref: "Products"
            },
            quantity: {
                type: Number,
                default: 1
            }
        }
      ],
    customerId: {
        type: Schema.Types.ObjectId,
        required: true,
        ref: "Customers"
    }
});

// create and export model
module.exports = mongoose.model("Orders", OrderSchema);
question from:https://stackoverflow.com/questions/65876723/mongoose-cannot-modify-field-value

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

findOneAndUpdate will only execute the query when a callback is passed. So in your case you can either add an await or callback.

await Product.findOneAndUpdate( filter, update );

or

Product.findOneAndUpdate( filter, update, callback );

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...