使用$set结合stringify失效,Express接口报语法错误求助
Hey there! Let's work through your issues one by one—first that annoying syntax error stopping your PUT interface, then figuring out why your $set + stringify approach isn't updating your MongoDB data.
1. Fix the "missing ) after argument list" Syntax Error
Looking at your code, two immediate syntax issues are causing that error:
- You left off the closing parentheses for the
FacturaModelconstructor and the route callback function. - The
...afterfactura.nombreis invalid syntax here (unless you meant to spread an array/object, but that's not what your code is doing right now).
Here's the corrected code snippet for the route structure:
app.put('/factura/:id', (req, res) => { res.header({'Content-Type': 'application/json'}); var factura = req.body; // Fixed: Closed all parentheses and removed invalid ... var facturaModel = new FacturaModel({ nro: factura.nro, nit: factura.nit, cliente: factura.cliente, tarjeta: factura.tarjeta, detalles: [{producto: factura.nombre}] }); // We'll add proper update logic below });
2. Correct Way to Update MongoDB Data with $set
The bigger issue is that your current code creates a new FacturaModel instance (which would insert a new document), not update the existing one with the :id from the URL. That's why your $set attempts weren't working—you weren't targeting the right document.
Here's how to fix this properly:
Step 1: Ensure Request Body Parsing
First, make sure you've enabled JSON body parsing in Express (required to access req.body correctly):
// Add this at the top of your file, before defining routes app.use(express.json());
You won't need JSON.stringify here—Express handles parsing the incoming JSON request body into a JavaScript object automatically.
Step 2: Use findByIdAndUpdate with $set
Replace your route code with this, which targets the specific document by ID and uses $set to update only the fields you want:
app.put('/factura/:id', async (req, res) => { try { const facturaId = req.params.id; // Define the fields you want to update const updateFields = { nro: req.body.nro, nit: req.body.nit, cliente: req.body.cliente, tarjeta: req.body.tarjeta, detalles: [{producto: req.body.nombre}] }; // Update the document: $set ensures only specified fields are changed const updatedFactura = await FacturaModel.findByIdAndUpdate( facturaId, { $set: updateFields }, { new: true, // Return the updated document instead of the original runValidators: true // Ensure your schema validation rules are applied } ); // Handle case where no document matches the ID if (!updatedFactura) { return res.status(404).json({ message: "Factura not found" }); } res.json(updatedFactura); } catch (error) { res.status(500).json({ message: error.message }); } });
3. Why Your Original Approach Failed
- Creating
new FacturaModel()is for inserting new documents, not updating existing ones. It has no connection to the:idin your URL. - Using
JSON.stringifywas unnecessary because Express already parses the request body into a usable object. If you tried to stringify and then pass it to MongoDB, it would store a string instead of structured data, which isn't what you want. $setonly works in MongoDB update operations (likefindByIdAndUpdateorupdateOne), not when creating new model instances.
内容的提问来源于stack exchange,提问作者Feber Castellon

