如何在JavaScript中一键将多组数组数据保存至MongoDB数据库
问题:MoneyIn交易流程仅保存最后一条商品数据
- 场景:用户在MoneyIn交易流程中输入多组商品名称、数量、价格等信息,点击蓝色保存按钮时,仅最后一条商品数据存入MongoDB
- 红色按钮功能:仅隐藏输入区域展示商品列表,不执行保存操作
- 需求:点击蓝色保存按钮时,同时保存所有商品数据与MoneyIn交易数据,控制台输出所有商品的数组格式
界面截图说明
- 商品输入表单:包含商品名称、数量、价格等输入字段,以及添加商品的操作按钮
- 商品详情添加后界面:展示已添加的商品列表,隐藏输入区域
- 保存按钮高亮界面:突出显示用于保存交易与商品数据的蓝色按钮
代码片段
前端React组件代码
const MoneyIn = () => { const [totalAmountIn, setTotalAmountIn] = useState(0); const [amountRecieved, setAmountRecieved] = useState(0); const [visible, setVisible] = useState(false); const [visible2, setVisible2] = useState(false); const [clicked, setClicked] = useState(false); const [productName, setProductName] = useState(""); const [sellingPrice, setSellingPrice] = useState(0); const [sellingPriceOfTotal, setSellingPriceOfTotal] = useState(0); const [balanceDue, setBalanceDue] = useState(0); const [itemDescription, setItemDescription] = useState(""); const [unitOfQuantity, setUnitOfQuantity] = useState(""); const [quantityCount, setQuantityCount] = useState(1); const [newItems, setNewItems] = useState([]); const [moneyInData, setMoneyInData] = useState([]); const [modeOfPayment, setModeOfPayment] = useState(""); let handleSaveItem = () => { const newItemData = { productName, sellingPriceOfTotal, quantityCount, unitOfQuantity, sellingPrice }; setNewItems([...newItems, newItemData]); } let handleSaveMonyIn = (event) => { event.preventDefault(); if (totalAmountIn === 0 || itemDescription === "") { setSeverity("error") setMessage("Enter Amount and Item Description"); setOpen(true) } else if (totalSellingPrice > totalAmountIn) { setSeverity("error") setMessage("Total Selling Prices cannot be bigger than Total amount"); setOpen(true) } else { const newMoneyInData = { totalAmountIn, amountRecieved, balanceDue, itemDescription, modeOfPayment }; setMoneyInData([...moneyInData, newMoneyInData]); // 保存到数据库 Axios.post('http://localhost:3500/moneyIn',{ totalAmountIn, amountRecieved, balanceDue, newItems, itemDescription, modeOfPayment }).then((response) => {alert('TRANSACTION CREATED')}).catch(function (error) { console.log(error); }); Axios.post('http://localhost:3500/newItems', {productName, sellingPriceOfTotal, quantityCount, unitOfQuantity, sellingPrice,totalSellingPrice}).then((response) => console.log(response)).catch((err)=> console.log(err)); console.log(newMoneyInData); document.getElementById("totalAndRecievedAmt").reset(); document.getElementById("itemDescriptionFrm").reset(); setSeverity("success"); setMessage("Saved Successfully !!!"); setOpen(true); setTotalAmountIn(0); setAmountRecieved(0); setBalanceDue(0); setItemDescription(''); setNewItems([]); } } }
MongoDB Schema代码
MoneyIn交易数据Schema
const mongoose = require ('mongoose') const moneyInDataSchema = new mongoose.Schema({ totalAmountIn:{ type: String, required: true }, amountRecieved:{ type: String, required: true }, balanceDue: { type: Number }, itemDescription:{ type: String }, modeOfPayment:{ type: String, required:true } }) module.exports = mongoose.model('MoneyInData', moneyInDataSchema)
商品数据Schema
const mongoose = require('mongoose'); const MoneyInData = require('./MoneyInData'); const newItemsSchema = new mongoose.Schema({ productName:{ type: String, required: true }, sellingPriceOfTotal:{ type: String, required: true }, quantityCount: { type: Number }, unitOfQuantity:{ type: String }, sellingPrice:{ type: Number, required:true }, sales:{ type: mongoose.Schema.Types.ObjectId, ref: 'MoneyInData' } }) module.exports = mongoose.model('NewItemsData', newItemsSchema);
控制器代码(商品数据增查)
const getAllNewItems = asyncHandler(async (req, res) => { const newItemsData = await NewItemsData.find().populate('sales').select().lean() if (!newItemsData?.length) { return res.status(400).json({ message: 'No rescent transaction' }) } res.json(newItemsData) }) const createNewItems = asyncHandler(async (req, res) => { const { productName, sellingPriceOfTotal, quantityCount, unitOfQuantity, sellingPrice}= req.body // 验证数据 if (!productName || !sellingPriceOfTotal || !quantityCount || !unitOfQuantity || !sellingPrice ) { return res.status(400).json({ message: 'All fields are required' }) } const newItemsObj = { productName, sellingPriceOfTotal, quantityCount, unitOfQuantity, sellingPrice } const addNewItems = await NewItemsData.create(newItemsObj) if (addNewItems) {// 创建成功 res.status(201).json({ message: 'New Item Recorded' }) console.log(addNewItems) } else { res.status(400).json({ message: 'Invalid Item' }) } })
问题原因与解决方案
核心问题
- 前端请求逻辑错误:点击保存交易时,仅发送了当前表单的单个商品字段,而非
newItems数组,导致后端只收到最后一条商品数据 - 交易与商品关联缺失:未将MoneyIn交易ID绑定到商品的
sales字段,无法建立数据关联
修复步骤
1. 前端修改:批量发送商品数组
替换handleSaveMonyIn中的请求逻辑,移除单个商品的POST请求,直接将newItems数组随交易数据一起发送:
// 保留交易请求,移除单独的商品请求 Axios.post('http://localhost:3500/moneyIn',{ totalAmountIn, amountRecieved, balanceDue, newItems, itemDescription, modeOfPayment }).then((response) => { alert('TRANSACTION CREATED'); console.log("所有商品数据:", newItems); // 控制台输出商品数组 }).catch(function (error) { console.log(error); });
2. 后端新增MoneyIn控制器:关联交易与商品
先创建交易记录,再批量创建关联商品(绑定交易ID到sales字段):
const createMoneyIn = asyncHandler(async (req, res) => { const { totalAmountIn, amountRecieved, balanceDue, newItems, itemDescription, modeOfPayment } = req.body; // 验证必填字段 if (!totalAmountIn || !amountRecieved || !modeOfPayment || !newItems?.length) { return res.status(400).json({ message: '交易核心字段和商品数据不能为空' }); } // 1. 创建交易记录 const moneyIn = await MoneyInData.create({ totalAmountIn, amountRecieved, balanceDue, itemDescription, modeOfPayment }); if (!moneyIn) { return res.status(400).json({ message: '创建交易失败' }); } // 2. 批量创建关联商品 const itemsWithSaleId = newItems.map(item => ({ ...item, sales: moneyIn._id })); const createdItems = await NewItemsData.insertMany(itemsWithSaleId); if (!createdItems?.length) { // 商品创建失败时回滚交易 await MoneyInData.findByIdAndDelete(moneyIn._id); return res.status(400).json({ message: '交易创建成功,但商品保存失败' }); } res.status(201).json({ message: '交易和商品数据保存成功', transaction: moneyIn, items: createdItems }); });
3. 前端优化:添加商品后清空输入
在handleSaveItem中添加清空逻辑,避免重复提交同一商品:
let handleSaveItem = () => { const newItemData = { productName, sellingPriceOfTotal, quantityCount, unitOfQuantity, sellingPrice }; setNewItems([...newItems, newItemData]); // 清空当前输入字段 setProductName(""); setSellingPrice(0); setSellingPriceOfTotal(0); setQuantityCount(1); setUnitOfQuantity(""); }
内容的提问来源于stack exchange,提问作者Aham_Uzoma
相关产品推荐
相关产品推荐

