MongooseError: Query was already executed: Todo.updateOne({ _id: new ObjectId("612df063a8f - javascript

I updated mongoose to latest version (6.0.2) and now I'm recieving this error and crush the application whenever .updateOne() is executed. But object update inside the database. My code:
async(req,res) => {
await Todo.updateOne(
{_id : req.params.id},
{
$set : {
status : "inactive"
}
},
(updateError) => {
// if updateError exist
if (updateError) {
// print error
printError(updateError);
// response the error
res.status(500).json({
error : "There was a Server Side Error!"
});
} else {
// if error dose not exist
// print message
console.log("|===> 🗂️ Data Was Updated successfully! 🗂️ <====|\n");
// response success
res.json({
message : "Todo Was Update successfully!"
});
}
});
}

Try to add .clone() to de updateOne function
async(req,res) => {
await Todo.updateOne(
{_id : req.params.id},
{
$set : {
status : "inactive"
}
},
(updateError) => {
// if updateError exist
if (updateError) {
// print error
printError(updateError);
// response the error
res.status(500).json({
error : "There was a Server Side Error!"
});
} else {
// if error dose not exist
// print message
console.log("|===> 🗂️ Data Was Updated successfully! 🗂️ <====|\n");
// response success
res.json({
message : "Todo Was Update successfully!"
});
}
}).clone();
}
Latest version of mongoose not duplicate execution
https://mongoosejs.com/docs/migrating_to_6.html#duplicate-query-execution

Since you are using async syntax, put your code in try/catch blok:
async (req, res) => {
try {
await Todo.updateOne({ _id: req.params.id }, { $set: { status: "inactive"}});
res.status(200).json({message: "Todo Was Update successfully!"});
} catch (error) {
res.status(500).json({error:'There was a Server Side Error!'})
}
}

Your async/await should look like this:
async (req,res) => {
try {
const result = await Todo.updateOne(
{_id : req.params.id},
{
$set : {
status : "inactive"
}
},
);
}
console.log('success', result)
res.json({message: "Todo Was Update successfully!", result })
} catch (err) {
console.log('error', err)
res.status(500).json({error:'There was a Server Side Error!'})
}
}

Related

Why I still get the 200 response status code instead of 404?

I just making delete query to mysql with sequelize.
const model = require('../../../config/model/index');
const controller = {};
controller.drop = async function(req, res) {
try {
await model.activitys.destroy({
where: {
id: req.params.id
}
})
check_id = model.activitys.findAll({
where: {
id: req.params.id
}
})
if(check_id!=null){
res.status(200).json({
status: "Success",
message: "Success",
data: {}
})
}else{
res.status(404).json({
status: "Not Found",
message: `Activity with ID ${id} Not Found`,
data: {}
})
}
} catch (error) {
res.status(404).json({
status: "Error",
message: error.message
})
}
}
module.exports = controller;
I want to delete the data on DB from id parameters, it's work for deleting the data. But when I try to delete by id that not exist in my DB, it's still get the 200 status code.
How to make that will return 404 status code if there's no data exists in DB ?
If you want to check if a single record exists in DB then use findOne or findByPk instead of findAll. findAll always returns an array (either empty or not) and that means it's always not equal to null:
check_id = model.activitys.findOne({
where: {
id: req.params.id
}
})

Node JS throwing cannot set headers after they are sent to the client, after using mongoose.removeOne

I have a method that deletes products and before it does it check if the user who is trying to delete the product is the user who created it. When i execute it with Insomnia it successfully removes the product but i get an error on the console saying cannot set headers after they are sent to the client.
My method:
exports.deleteProduct = (req, res) => {
const id = req.params.productId;
Product.deleteOne({ _id: id, userId: req.user._id }, () => {
return res.status(401).json("Not authorized");
})
.then(() => {
return res.status(200).json("Product deleted");
})
.catch((err) => {
return res.status(500).json({
error: err,
});
});
};
I'm pretty sure this is happening because I'm chaining a .then() and .catch() after executing it.
I tried to do this but it didn't work because the err parameter that I'm sending to the callback function is null.:
exports.deleteProduct = (req, res) => {
const id = req.params.productId;
Product.deleteOne({ _id: id, userId: req.user._id }, (err) => {
if (err) {
return res.status(401).json("Not authorized");
}
return res.status(200).json("Product deleted");
});
};
When i tried this second approach I always got the 200 status, meanwhile the product didn't delete.
Any idea how to deal with this?
You can try something like this:
Product.deleteOne({ _id: id, userId: req.user._id }, (err, result) => {
if(err) {
return "something"
}
return "something else"
});
or: in async / await way
try {
await Product.deleteOne({ _id: id, userId: req.user._id });
} catch (err) {
// handle error here
}
By the way, why you are passing userId at the deleteOne method?

MongoError: filter parameter must be an object

I am creating a rest api I have end point for Post/Movies: Request body should contain only movie title, and its presence should be validated Based on passed title, other movie details should be fetched from thememoviedb,and saved to application database.
app.post('/movies', (req, res) => {
request('https://api.themoviedb.org/3/discover/movie?callback=JSONP_CALLBACK&sort_by=popularity.desc&api_key=2931998c3a80d7806199320f76d65298', function (error, response, body) {
console.log('error:', error); // Print the error if one occurred and handle it
console.log('statusCode:', response && response.statusCode); // Print the response status code if a response was received
});
db.collection('movies').findOneAndUpdate(req.body.title,{
title: 'Avengers',
},(err, result) => {
if (err) {
res.send({
'error': 'An error has occured'
});
} else {
res.send(result.ops[0]);
}
});
});
when I run the app I get this error, what am I doing wrong here,? am new to nodejs and all this stuff just learning
Use $eq operator in the filter object $eq
{ <field>: { $eq: <value> } }
So the final snippet becomes like this:
app.post('/movies', (req, res) => {
/* code ... */
let { title } = req.body
db.collection('movies').findOneAndUpdate({ title: { $eq: title } }, { title: 'Avengers' }, (err, result) => {
if (err) {
res.send({ 'error': 'An error has occured' });
} else {
res.send(result.ops[0]);
}
});
});
Try the following,
db.collection('movies').findOneAndUpdate({title:req.body.title},{
$set:{
'Avengers'
}})

Post data to mongodb

Hi i have end point to post data to mongodb , when i submit a form only ID is submitted I think because am using insert instead of save ,
Here is how it looks:
app.post('/comments', (req, res) => {
const { errors, isVal } = validate(req.body);
if (isVal){
const { author, description } = req.body;
db.collection('comments').insert({ author, description }, (error, result) => {
if (error) {
res.status(500).json({ errors: { global: "Oops something is right!" }});
} else {
res.json({ comments: result.ops[0] });
}
})
} else {
res.status(400).json({ errors });
}
});
The method above is the one saves only ID, other data saved null: I tried to change like this, replacing insert with save some one suggested something like this.
app.post('/comments', (req, res) => {
const { errors, isVal } = validate(req.body);
if (isVal){
const { author, description } = req.body;
db.collection('comments').save({ author, description }, (error, result) => {
if (error) {
res.status(500).json({ errors: { global: "Oops something is right!" }});
} else {
res.json({ comments: result.ops[0] });
}
})
} else {
res.status(400).json({ errors });
}
});
Still the same : here is the result saved in database:
{
"_id": {
"$oid": "5b281457f5b629565c09ce26"
},
"author": null,
"description": null
}
how can I change my method so that it can use save instead of insert?
and what is the different between save and insert in mongodb?
Try with this
let newcollection = db.collection('comments');
newcollection.insert({})

Calling async function in node.js

I have an async function
async function getPostAsync() {
const post = await Post.findById('id');
// if promise was successful,
// but post with specific id doesn't exist
if (!post) {
throw new Error('Post was not found');
}
return post;
}
I am calling the function with
app.get('/', (req, res) => {
getPostAsync().then(post => {
res.json({
status: 'success',
});
}).catch(err => {
res.status(400).json({
status: 'error',
err
});
})
});
but I just receive
{
"status": "error",
"err": {}
}
I would expect to either get the error Post was not found or some error with the connection or something like that, but the variable err is simply an empty object in my catch statement.
Consider the following:
let e = Error('foobar');
console.log( JSON.stringify(e) )
This outputs {}, much like in your case. That's because errors don't serialize to JSON very well.
Instead, try this:
res.status(400).json({
status : 'error',
err : err.message // `String(err)` would also work
});

Categories

Resources