router.delete('/:id', function(req, res){
user.remove({
_id: req.params.id
}, function(err, users) {
if(err) {
res.status(404).send({
message: "Invalid User",
data: []
});
} else {
res.status(200).send({
message: "User deleted",
data: []
});
}
});
});
I tried to implement the DELETE endpoint for my RESTful API.
It successfully deletes an existing data when I test it on postman,
but when I try to delete an invalid data, it still gives me a delete message
with a response status of 200.
What mistake am I making?
That right when you delete an not exist data the code work fine .
But you can check in users values it return nMatched if working in mongodb.
and for all database they contain this type of flag (here flag means 'nMatched' field in users object , you can check by printing users object ). for mongodb they contains values in 0 or 1
Can you something like this.
function(err, users) {
if(err) {
res.status(404).send({
message: "Invalid User",
data: []
});
} else if (users.nMatched === 0) {
res.status(400).send({
message: "User not exist deleted",
data: []
});
} else {
res.status(200).send({
message: "User deleted",
data: []
});
}
});
Related
this will be a simple answer, but I have this code, that validates if a record exists in the database, and It does, and I got a status 500 from the API call, but keeps creating the duplicate record in my table.
exports.createBet = async (req, res)=>{
betBody = req.body;
newBalance = 0.0;
Bet.findOne({
where: {
[Op.and]: [
{match_id: betBody.matchId},
{user_id: betBody.userId}
]
}
}).then(data=>{
if(data){
return res.status(500).send({message: "Bet already made for this match"});
}
})
.catch(err=>{
return res.status(500).send({ message: "Error creation the bet: " + err.message});
});
balnce = await User.findOne({
where:{
id: betBody.userId
}
})
.then(data=>{
if(data.balance < betBody.betAmount){
return res.status(500).send({ message: "Not enough balance to make that bet."});
}
return data.balance;
})
.catch(err=>{
return res.status(500).send({ message : "Error getting the user in the bet creation: " + err.message})
});
Bet.create({
match_id: betBody.matchId,
bet_amount: betBody.betAmount,
selected_winner: betBody.teamSelect,
user_id: betBody.userId
})
.then(data=>{
res.json(data)
})
.catch(err=>{
return res.status(500).send({ message: "Error creating the bet: " + err.message})
});
newBalance = balnce - betBody.betAmount;
User.update(
{ balance: newBalance},
{ where: {id: betBody.userId}}
)
.catch(err=>{
res.status(500).send({ message: "Error getting user: " + err.message})
});
};
Here it is the response of the api call
And here it is the duplicated records in my table
You should use the promise chain(or async/await correctly) to solve this issue, When a request reaches to createBet function every database call(without await one) is executing parallel, it creates a new record while checking for the existing one.
NOTE: Sometimes You might get a response already sent error. res.send does not stop execution it'll return the response but the remaining code will still execute.
exports.createBet = async (req, res) => {
betBody = req.body;
newBalance = 0.0;
try {
const bet = await Bet.findOne({
where: {
[Op.and]: [{ match_id: betBody.matchId }, { user_id: betBody.userId }],
},
}).catch((err) => {
throw { message: "Error creation the bet: " + err.message };
});
if (bet) {
throw { message: "Bet already made for this match" };
}
//... handle the cases like above, must use await
} catch (err) {
res.status(500).json({ message: err.message });
}
};
This problem causes in your database a saved record without all the fields trying to truncate your table and start a fresh,
I think here in your query all time finds a record(data) thats why we are facing this type of error
If it's not work try to debug your code with log your data which comes from your findOne query
I want to use error and result data in my controller, but got a little bit confused and always got this response :
{
"status": "fail",
"message": "Cast to ObjectId failed for value \"60f943dd4bef612ae873d34\" (type string) at path \"_id\" for model \"Student\""
}
But i get this response when the data is not found :
}
"status": "fail",
"message": "Cannot delete student data with id 60f943dd4bef612ae873d34. Student data was not found
}
My code as follows :
deleteOneStudent: async (req, res) => {
const { _id } = req.params;
const student = Student.findById({ _id });
await Student.exists({ _id }, async (err, data) => {
if (err) {
return res.status(500).json({
status: "fail",
message: err.message || "Some error occurred while deleting student data."
});
}
if (!data) {
return res.status(404).json({
status: "fail",
message: `Cannot delete student data with id ${_id}. Student data was not found`
});
} else { //the code below is for removing ref from Semester document when deleting Student document
await Semester.updateMany({ '_id': student.semester }, { $pull: { student: student._id } }, { new: true, useFindAndModify: false })
student.remove()
return res.status(200).json({
status: "success",
message: "Student data was deleted successfully",
});
}
})
},
if I remove the first if, everything works fine, but I want to utilize 404 , 500 , and 200 altogether, and I have no idea using .then() and .catch() either. Can anyone help me? Thanks in advance
It looks _id casting issue. You can wrap _id in mongoose.Types.ObjectId
await Student.exists({ _id:mongoose.Types.ObjectId(_id) }, async (err, data) => {
if (err) {
return res.status(500).json({
status: "fail",
message: err.message || "Some error occurred while deleting student data."
});
}
....
....
deleteOneStudent: async (req, res) => {
try{
const { _id } = req.params;
const student = Student.findById({ _id });
await Student.exists({ _id }, async (err, data) => {
if (err) {
return res.status(500).json({
status: "fail",
message: err.message || "Some error occurred while deleting student data."
});
}
if (!data) {
return res.status(404).json({
status: "fail",
message: `Cannot delete student data with id ${_id}. Student data was not found`
});
} else { //the code below is for removing ref from Semester document when deleting Student document
await Semester.updateMany({ '_id': student.semester }, { $pull: { student: student._id } }, { new: true, useFindAndModify: false })
student.remove()
return res.status(200).json({
status: "success",
message: "Student data was deleted successfully",
});
}
})
}
catch(error){
return res.status(500).json({
status: "fail",
message: error,
});
}
}
I'm implementing user authentication in my Node REST API.
I have defined in the UserController a method to remove a user:
async function remove(req, res) {
try {
User.findOneAndRemove({ _id: req.params.id });
return res.status(200).json({
message: 'user deleted',
});
} catch (err) {
console.log(err);
res.status(500).json({
error: err,
});
}
}
When I hit the route in Postman with an id from a user stored in the database, I get the success message: "user deleted"
However when I look in the database, the user is still there.
What am I doing wrong?
thanks for your help!
dough, forgot to put 'await' before User.findOneAndRemove ...
My Mongoose Function
Error Message: Cast to ObjectId failed for value "count" at path "_id" for model "myinfo""
exports.indexCount = function(req, res) {
MyInfo.countDocuments({}, function(err, count) {
if (err) {
res.json({
status: "error",
message: err,
});
}
console.log("Number of users:", count);
res.json({
status: "success",
message: "Count info retrieved successfully",
data: count,
});
});
};
The problem was with my route
Since i already have a route "/myinfo/:id". my mistake was i am using
"/myinfo/count" route for getting count values which is wrong.
because count is mapped as :id in my above route
i changed the "/myinfo/count" to "/myinfo/get/count" it works now.
I have a object in mongodb. I want to filter their sections using status. If status is active then only that has to be sent to the user.
Structure of the Course schema is:
{
_id: 'ObjectId',
name: 'NODE JS',
.
.
sections: [
{status: 'active', trainer: 'XYZ'}, {status: 'inactive', trainer: 'YZX'}, .....
]
}
below 'sections.status': 'active' is working properly for filtering the courses but it is returning all the sections which are not active. How can I filter the array in mongoose query itself. Without handling the query results.
Course.findOne({ _id: req.params.id , 'sections.status': 'active' })
.exec((err, course) => {
if (err) {
logger.error(err);
res.status(500).json({ success: false, message: 'Error in getting data' });
} else if (!course) {
res.status(404).json({ success: false, message: 'No course details found' });
} else {
res.json({ success: true, course });
}
});
You can't have Mongoose return a modified document for you without writing it to the database. However, you can use the lean function to have Mongoose return an object literal, without the added overhead of the full model itself, and modify that object as you wish to send with your data.
Course.findOne({ _id: req.params.id , 'sections.status': 'active' })
.lean()
.exec((err, course) => {
if (err) {
logger.error(err);
res.status(500).json({ success: false, message: 'Error in getting data' });
} else if (!course) {
res.status(404).json({ success: false, message: 'No course details found' });
} else {
// Remove all 'inactive' sections
course.sections = course
.sections
.filter((section) => section.status === 'active')
res.json({ success: true, course });
}
});
See the following post for a reference.
Why can't you modify the data returned by a Mongoose Query (ex: findById)