Nodejs inserting data to mongodb. It takes too much time - node.js

Hi i am developing nodejs application. I am inserting data to mongodb but my page always in 'loading' mode. But strange thing is my data inserted to mongodb immediately but page load not stopping. My code is shown below:
app.post('/Management/Post/New',function(req, res){
new Post({
title:req.body.post.title,
body:req.body.post.body,
keywords:req.body.post.keywords
}).save(function (err, docs){
if(err) {
return res.render(__dirname + "/views/createpost", {
title: 'Yeni Gönderi Oluştur',
stylesheet: 'postcreate',
error: 'Gönderi oluşturulurken bir hata ile karşılaşıldı'
});
}
console.log('Gönderi oluşturuldu');
});
});
Have no idea.

You only send a response when there is an error. If there's no error, you server never sends anything back: that's why the page seems to always be loading.
You need to send a response when you have no error, like this:
.save(function (err, docs){
if(err) { // Executed when there was an error with Mongo
return res.render(...);
} else { // Executed when everything is fine
return res.render(...);
}
});

You aren't handling the success scenario except for a console.log. You need a res.render() or res.redirect() on success, not just error

Related

How to do AJAX POST call in express.js file in handlebar?

I am trying to send/update data to mongoDB database via AAJAX call but the command is not reaching theere. I have tried debugging using alert in between the code but the command is not reaching there. Means AJAX call doesn't get executed.
Below is my AJAX POST request code:
var text = "Done";
var data = {
selectedValue: text
}
$ajax({
method: 'POST',
url: '/update-sources',
dataType: 'text/json',
data: data,
success: function(data){
console.log(data);
alert("Working!!")
}
});
And Below is the /update-sources route code:
router.post('/update-sources', function(req, res, next) {
console.log("/Update-Sources")
User.findOneAndUpdate({email: req.user.email}, {$set:{status:data.selectedValue}}, {new: true}, (err, doc) => {
if (err) {
console.log("Something wrong when updating data!");
}
else
{
res.render('taskswriter');
console.log(doc);
return "Great Working!";
}
});
});
What mistake I am doing?
Would be great if you shared browser's console output, but trying to execute attached client-side snippet, I got the following error:
VM219:7 Uncaught ReferenceError: $ajax is not defined
at <anonymous>:7:1
You've got a typo there - it should be $.ajax as you are accessing a function from within jQuery namespace (https://api.jquery.com/jQuery.ajax/)

Handling 503 Error in Express/Node.js especially in TryCatch case

I have a special case for which I want to clear the possible reason for 503 Error. The following code snippet has a catch statement which runs when system is not able to find any results
app.post('/api/fetch/user', function(req, res){
var email = req.body.emailTxt;
db.one('SELECT * FROM users WHERE email=$1', [email])
.then(function(data){
console.log('DATA:', data);
var userCard = { id: data.user_id, name: data.user_name,
email: data.email, regDate: data.date_created };
res.status(200).json({ 'valid': true, '_payload': userCard });
})
.catch(function(error){
if(error.search(/No data returned from the query/im) > 0) // regex case insensitive search and search multiline as source string is multiline
res.status(500).send('Invalid Request Match');
else
res.status(500).send('ERROR: '+error);
})
});
When my API call is made to this API end point and when no result found the control moves in catch() which is fine but quite strangely it returns 503 - Request timeout error.
I have tried to to remove conditions in if() in order to debug but seems like no matter what but the if-else does not seem working in ExpressJs.
Note: Everything works well and also when control stays in .then(). If I remove if,else and keep simple error display/response return then everything works ok. There is nothing special included in my API; it is only one single page script I prepared to test API.
I think you got error in the .catch block.
Try to modify the code and see if this helps:
app.post('/api/fetch/user', function(req, res){
var email = req.body.emailTxt;
db.one('SELECT * FROM users WHERE email=$1', [email])
.then(function(data){
console.log('DATA:', data);
var userCard = { id: data.user_id, name: data.user_name,
email: data.email, regDate: data.date_created };
res.status(200).json({ 'valid': true, '_payload': userCard });
})
.catch(function(error){
console.error(error); //never ignore errors!
try {
//i think error is an Error Object here, so it doesn't have .search function
if(error.search(/No data returned from the query/im) > 0) // regex case insensitive search and search multiline as source string is multiline
res.status(500).send('Invalid Request Match');
else
res.status(500).send('ERROR: '+error);
} catch (err) {
console.error(err);
res.status(500).send('some unknown error');
};
});
});
Edit: Sorry, removed .finally because you may send response twice.
Edit, better approach to handle error in .catch block.
//make catch block error safe to make sure no error occurs
if (error && error.message == 'No data returned from the query.') {
res.status(500).send('Invalid Request Match');
} else {
res.status(500).send('ERROR: '+error);
}
We use response codes in ExpressJs quite intensively when creating an API service. So it seems a right way that we make use of them directly instead of doing if-else in catch().
Hence, the right way would be:
.catch(function(error){
console.log('ERROR:', error);
res.status(204).send('No Content; Invalid Request Match');
})
However, If you want to display/return detailed message you can do that as well. You can check: http://expressjs.com/en/api.html#res for details on ways you can response back. You can render an HTML template, or return JSON response or even multiline text.
I don't know why if-else creates problem but you can go other way around.
In your specific case the error does not have .search() method attached to it. So better to parse it to string first using .toString();.

regenerate session on db callback

I am trying to regnerate session on successful validation of user credentials.But the session doesn't get regenerated when the code is in db callback
app.post('/login',function(req,res){
var userName=req.body.userid.toLowerCase();
db.collection('credentials').findOne({'userName':userName},function(err,result){
req.session.regenerate(function (err) {
});
});
});
It works fine out side it
app.post('/login',function(req,res){
var userName=req.body.userid.toLowerCase();
req.session.regenerate(function (err) {
});
db.collection('credentials').findOne({'userName':userName},function(err,result){
});
});
Any ideas?
Looks like the mistake was on my part.The code was responding to the request right below the code i posted. Since these work in async, I guess the response was sent beofre the session was reset.
app.post('/login',function(req,res){
var userName=req.body.userid.toLowerCase();
db.collection('credentials').findOne({'userName':userName},function(err,result){
req.session.regenerate(function (err) {
});
res.send('welcome '+result.firstName+' '+result.lastName);
});
});
I moved the response inside the regenarte call back and it is working now.

Node js (Express) freezing in mongodb operation

I have a code that accepts a post request and inserts a string into mongodb database.
app.post('/post_comment', function(req, res) {
Predicts.findOne({'id': parseInt(req.body.id)}, function(err, card) {
console.log('')
console.log(card)
console.log('')
if (card) {
Users.findOne( { 'userid': req.user ? req.user.userid : undefined }, function(err, user) {
console.log(user)
console.log('')
Predicts.update({'_id': card._id},
{$push : {comments: {login: user ? user.login : 'anonymous', content: '123'}}},
function(err, card1) {throw(err);
console.log('---')
console.log(card1);
})
})
}})
res.redirect('back')
})
This code result in total freezing of node process. Only restart of the node process can help.
Debugging shows, that first four console.log operations work as supposed, but console.log('---') doesn't happen. This means that Predicts.update doesn't work, but it is really works, and I can see the result of this request in the database. What's the hitch?
Upd: I have replaced Predicts.update to Predicts.find but result is still the same. Collback doesn't work, and node process freezing.
Upd2: I established that node is not freezing, but returns only content that doesn't require to mongodb.
According to the node-mongodb docs, the update function looks like:
collection.update(criteria, objNew, options, [callback]);
So if you want to use a callback, it should be the 4th parameter, and the 3rd should be your options (e.g. multi:true) or else {}.

app.render() not displaying in browser

I'm trying to use app.render() to display a jade file in the browser. In the following code, the html is displayed to the console correctly, but the browser never shows the related file.
app.render('unavailable', {title: 'Unavailable'}, function(err, html){
console.log(html);
});
EDIT:
I have this handler:
app.get('/unavailable', display.unavailable);
Then beneath this code in the same file (app.js) I have this:
sql.open(connStr, function(err, sqlconn){
if(err){
console.error("Could not connect to sql: ", err);
else
conn = sqlconn; //save the sql connection globally for all client's to use
});
So, what I want to happen is when the err happens with the SQL connection, the /unavailable handler is executed and a static html page is displayed that says the service is down. However, because the error occurs on the server, and not the client, I don't have access to a response object at that time. I'm trying to artifically manufacture the client 'redirecting' to /unavailable in their browser to see the message.
Obviously you don't send the html to the browser. Use res.render inside a route without callback, i.e.
res.render('unavailable', {title: 'Unavailable'});
or send the result of rendering like here:
app.render('unavailable', {title: 'Unavailable'}, function(err, html){
console.log(html);
res.send(html);
});
Read more about the difference here:
What's the difference between "app.render" and "res.render" in express.js?
save a global var sqlOK = false, set it in sql.open callback, and redirect to /unavailable if you get a request while sqlOK is not true. you were also missing brackets around the else statement.
var sqlOK = false;
app.get('/unavailable', display.unavailable);
app.get('*', function(req, res, next){
if(!sqlOK){
return res.redirect('/unavailable');
//return res.send(500)
};
next();
});
sql.open(connStr, function(err, sqlconn){
if(err){
console.error("Could not connect to sql: ", err);
} else {
conn = sqlconn; //save the sql connection globally for all client's to use
sqlOK = true
}
});

Resources