I'm trying to save information to my user schema in my database. I'm doing this using "user.save" but for some reason the code within the parenthesis is not run.
user.save(function(err) {
//THIS CODE DOESNT SEEM TO RUN
if (err) {
console.log(err);
} else {
res.json({ message: 'given a reset-token' })
}
//
});
So I switched to the following code since I needed to get a success message from the server:
user.save((err) => {
console.log('hello');
if (err) {
console.log(err);
console.log('err2');
res.status(404).json({ message: 'Save error' });
}
}).then(() => {
res.status(201).json({ message: 'Activated' });
});
Witch successfully sends me the status code when changes to the user have been pushed to the database. Could anyone explain why the second one works and the first one doesn't? And if there is a better way to write this code?
Related
I am stuck in a bit of a dilemma here where once my user logs in I want to redirect them to the dashbord page but also send their json details to my client side javascript. I know that there can only be one res. send /end/json in a response and that I can send dynamic data using view engines.The reason why I want to send data separately is because I do not merely want to render it but rather use the data in my client side JS so that I can use it later for sockets in a chat application. I have tried a lot of things from using continuous local variables to try and create a middleware or an automatic redirect. The problem is no matter what the res.json() is hard to embed in a middleware as the very moment it is called there is no scope for declaring a next or redirect. Here is what my code looks like for the login route:
router.get(’/’, (req,res)=>{
console.log(req.user._id);
User.findOne({
"_id": req.user._id
}, function(err, foundUser) {
if (err) {
console.log(err);
return res.status(500).json({
ok: false,
error: err
});
} else {
console.log(foundUser); //THE ELEMENT IS FOUND
return res.status(200).json({
ok: true,
data: foundUser
});
}
});
res.sendFile('chat.html', { root: path.join(__dirname, '../views/') });
});
you can make ajax request from your page to fetch the data you want and save it in your client side.
You need to make your chat.html page request the json data. This means you need two routes:
router.get(’/’, (req,res)=>{
es.sendFile('chat.html', { root: path.join(__dirname, '../views/') });
});
router.get(’/myself’, (req,res)=>{ // I normally call this route "myself"
// but you can call it anything you want
console.log(req.user._id);
User.findOne({
"_id": req.user._id
}, function(err, foundUser) {
if (err) {
console.log(err);
return res.status(500).json({
ok: false,
error: err
});
} else {
console.log(foundUser); //THE ELEMENT IS FOUND
return res.status(200).json({
ok: true,
data: foundUser
});
}
});
});
Now you need your chat.html file to make a request for the new /myself data. There are various ways to do this but for modern browsers you can use fetch:
chat.html
<html>
<head>
... rest of your html head
<script>
fetch('/myself')
.then(res => res.json())
.then(res => {
if (res.ok === false) {
// Handle your error here, I'm just alerting it:
alert(res.error);
}
else {
let user = res.data;
// Now you can do anything with the user data
// in here. I'm just logging it:
console.log('user =', user);
}
});
</script>
</head>
<body>
... rest of your html code
</body>
</html>
My call to Express's 'res.send(string)' fails to redirect and display the provided text upon completion of a call to MongoDB's 'deleteMany()'. The database is cleared and no error is thrown.
I've tried adjusting my call to 'res' with 'res.json()' and such, but to no avail. I've also adjusted the ordering my other calls within the 'delete' request, with no success. My inclination is that my issue is related to Promises.
.delete(function(req, res){
//if successful response will be 'complete delete successful'
console.log('deleting all documents');
MongoClient.connect(MONGODB_CONNECTION_STRING, { useNewUrlParser: true }, (connectErr, client) => {
if(connectErr) res.json({ "error": "Error connecting to database!", "error": connectErr });
const db = client.db('test-db');
try {
db.collection('testCollection2').deleteMany({}, (err) => {
if(err) throw err;
res.send('complete delete successful');
console.log('complete delete successful');
});
} catch(err) {
console.log('Complete delete failed!');
res.send('Complete delete failed!');
}
});
});
Despite not redirecting or receiving an error message, I still receive the console.log output confirming the successful call to 'deleteMany'. I'm not sure how to test this in more depth, since I'm using Glitch for the project. Thanks in advance for any help!
As you know Node.js statements are async. So I write code in following way. But I can't make sure if the connection is released or not.
Why, because I'm writing connection.release() just after res.json(). In my view, once we send response the control doesn't pass to next statement (Query 1: Is it true?). So should I write it before I send response?
Query 2: res.json() / res.end() and connection.release() both are async methods. Is it true?
Query 3: Even if the following code works perfectly, can I write connection.release() only once, i.e., just when if else statement ends? If yes, why doesn't next() works after res.end()` in Node.js?
connection.query(query, [body.endDate, tripId], function (err, rows, fields) {
if (err) {
res.status(422).json(
{
status: "error",
data: {error: {code: err.code, sqlMessage: err.sqlMessage}},
message: "Something didn't work."
}
);
connection.release();
} else {
res.status(200).json(
{
status: "success",
data: {affectedRows: rows.affectedRows},
message: "Trip ended."
}
);
connection.release();
}
});
I am trying to figure out how to handle an error when deleting or updating a document in MongoDB in Angular JS?
I have the following route in Node/Express:
function handleError(res, reason, message, code) {
console.log("ERROR: " + reason);
//log the reason for the error
res.status(code || 500).json({
"error": message
});
}
app.delete("/polls/:id", auth, function(req, res) {
db.collection(POLLS_COLLECTION).deleteOne({
_id: new ObjectID(req.params.id), userID: req.user.id
//userID must match the req.user.id from Passport to make sure the poll belongs to the user
}, function(err, doc) {
if (err) {
handleError(res, err.message, "Failed to delete poll");
} else {
res.status(204).end();
}
});
});
The following in an Angular JS controller:
$scope.deleteThisPoll = function(){
Polls.deletePoll($routeParams.pollId)
.then(function(response){
alert("Poll deleted!");
var url = "/mypolls/" + $scope.userID;
$location.path(url);
}, function(response){
alert("Error deleting poll");
console.log(response);
})
};
deleteThisPoll in the controller calls a deletePoll service that sends a a request to the route:
this.deletePoll = function(pollId){
var url = "/polls/" + pollId;
return $http.delete(url);
};
What I want is to alert "Error deleting poll" from the Angular controller when the database delete is not executed (because for example user is not authenticated or the poll doesnt belong to the user) and "Poll Deleted" when the delete was successfull.
However: the error callback is never used and the app always alerts "Poll deleted!" no matter if the document was deleted or not deleted.
Doesn't my route send an error response when the delete was not executed and will it not hit my Angular error callback?
You can do like code below
Put this HTML code where you want to show error message :
<div style="color:red;">
{{error}}
</div>
In your angular js controller :
$scope.deleteThisPoll = function(){
Polls.deletePoll($routeParams.pollId)
.then(function(response){
alert("Poll deleted!");
var url = "/mypolls/" + $scope.userID;
$location.path(url);
}, function(response){
$scope.error="Any error message you like to show";
console.log(response);
})
};
If your API return an error. you can catch it like this :
Polls.deletePoll($routeParams.pollId).then(function(response) {
//SUCCESS CODE
}).catch(function(error) {
//NOTIFY ERROR
//NotifyService.display(error);
console.log(error);
});
thanks guys. I found out that MongoDB for some reason always returns a result object even when there was no delete/update. I solved this by checking for the result.deletedCount propety that is set to 1 or 0. Like so:
if(err){
res.status(500).end();
}
if(result.deletedCount === 0){
res.status(404).end();
//error handling in Angular error callback
} else {
res.status(204).end();
//error handling in Angular success callback
}
});
});
this makes sure that not always a 204 is send whether or not the delete was successfull.
apiRoutes.put('/intake/:id', function(req, res) {
var id = req.params.id;
Intake.findById({id, function(err, intake) {
if (err)res.send(err);
intake.check = true;
intake.save(function(err) {
if (err) {return res.json({success: false, msg: 'Error'});}
res.json({success: true, msg: 'Successful update check state.'});
});
}})
});
What's problem? In console i see ID, it's ok, but database have no change
Intake.findById(/*remove { here*/id, function(err, intake) {
if (err)res.send(err);
intake.check = true;
intake.save(function(err) {
if (err) {return res.json({success: false, msg: 'Error'});}
res.json({success: true, msg: 'Successful update check state.'});
});
})
You gave us too few information to help you. But I got some hints on how to find out what's going wrong: (I added example code a the end of my answer.)
Use a proper formatting of your code. Mistakes are easier to find.
Please avoid res.send(err). Most express apps provide an error to HTML Page translation at the end of the route pipe. This only works if you call res.next(err);. If your app does not provide error page generating at the end of the pipe then, you could use res.status(400).json({success: false, msg: err.message});.
After the use of res.send or res.next or res.json you have to end the execution of the function by return before one of these functions can be called a second time. This can be very complicated in case of nested or asynchrounous method calls. But in your example it's quite easy.
Use some log outputs to see which part of the code you reach and which not.
console.dir(<object>); prints out the structure of this object.
Hope this helps a little bit. ;-)
apiRoutes.put('/intake/:id', function(req, res)
{
var id = req.params.id;
Intake.findById(id, function(err, intake)
{
if (err)
{
res.next(err);
console.error(err);
return;
}
console.log("Modify check attribute");
intake.check = true;
console.dir(intake);
intake.save(function(err)
{
console.log("Intake save called!");
if (err)
{
console.error(err);
res.json({
success: false,
msg: 'Error'
});
return;
}
console.log("Success");
res.json({
success: true,
msg: 'Successful update check state.'
});
});
}})
});
you can use this
Intake.update({_id: req.params.id},
{
check : true
},
function(err){
if(err){
console.log(err);
res.status(400).send(err.errors);
}else{
res.status(200).end();
}
});