Pretty sure this is a quite noobish node.js/callback question but I can't seem to find the proper code to make it run.
This is how I invoke my node-mysql code:
var utils = require('../../config/database/utils');
exports.getResults = function(callback) {
var query = "SELECT * FROM my_table";
utils.exec(query, null, function(err, results){
if(err){
console.log(err);
callback(true);
return;
}
console.log(results);
callback(false, results);
});
};
Next is the utils file where I can't get the code work.
var pool = require('./connection');
module.exports = {
getDBConnection: function() {
pool.getConnection(function(err, connection){
if(err){
console.log(err);
return;
}
return connection;
});
},
endDBConnection: function(connection) {
connection.end(function (err) {
if(err) {
console.log(err);
callback(true);
return;
}
});
},
exec: function(query, data, callback) {
console.log(query);
this.getDBConnection(function(err, connection){
if(err){
console.log('error');
}
console.log(connection);
connection.query(query, data, function(err, results) {
if(err) {
callback(err);
}
callback(false, results);
});
this.endDBConnection(connection);
});
}
}
Code is getting OK the the exec part since the console.log(query) logs the query. But after that, the code's not running, console.log(connection); doesn't show a thing, and of course the connection.query is also not running.
I'm not sure why this is happening.
Returning a value inside a callback is meaningless. You need to pass in a callback that gets called with the value you want to return:
getDBConnection: function(callback) {
pool.getConnection(function(err, connection){
if(err){
console.log(err);
return callback(err);
}
callback(null, connection);
});
},
You should also use connection.release() instead of connection.end() since you are using a pool:
endDBConnection: function(connection) {
connection.release();
},
In exec(), you have the wrong this. It should instead be something like:
exec: function(query, data, callback) {
console.log(query);
var self = this;
this.getDBConnection(function(err, connection){
if(err){
console.log('error');
return callback(err);
}
console.log(connection);
connection.query(query, data, function(err, results) {
self.endDBConnection(connection);
if(err) {
return callback(err);
}
callback(null, results);
});
});
}
Related
How do I get the return value from inside a value of node.js/javascript callback?
function get_logs(){
User_Log.findOne({userId:req.user._id}, function(err, userlogs){
if(err) throw err;
if(userlogs){
// logs = userlogs.logs;
return "hello there is a logs";
} else {
return "there is no logs yet..."
}
})
}
var logs = get_logs();
console.log(logs);
You can't return the result from a function whose execution is asynchronous.
The simplest solution is to pass a callback :
function get_logs(cb){
User_Log.findOne({userId:req.user._id}, function(err, userlogs){
if(err) throw err;
if(userlogs){
// logs = userlogs.logs;
cb("hello there is a logs");
} else {
cb("there is no logs yet...)"
}
})
}
get_logs(function(logs){
console.log(logs);
});
You can't. You should instead pass another callback to your function. Something like this:
function get_logs(callback){
User_Log.findOne({userId:req.user._id}, function(err, userlogs){
if(err) throw err;
if(userlogs){
callback("hello there is a logs");
} else {
callback("there is no logs yet...");
}
})
}
get_logs(function(arg1) {
console.log(arg1);
});
function get_logs(callback) {
User_Log.findOne({
userId: req.user._id
}, function (err, userlogs) {
if (err) throw err;
if (userlogs) {
// logs = userlogs.logs;
callback("hello there is a logs");
} else {
callback("there is no logs yet...");
}
})
}
get_logs(function (data) {
console.log(data);
});
Uses callbacks...
In node.js almost all the callbacks run after the function returns , so you can do something like this
function get_logs(){
User_Log.findOne({userId:req.user._id}, function(err, userlogs){
if(err) throw err;
if(userlogs){
// logs = userlogs.logs;
do_something(logs)
} else {
console.log('No logs')
}
})
}
the console.log in the showBets function is working fine, but not the res.write. Am i misunderstanding how it works? The documentation is not making me any wiser.
app.js
var queryString = 'SELECT * FROM bets';
router.get("/bets",function(req, res){
showBets(res);
res.sendFile(path + "bets.html");
});
function showBets(res){
connection.query(queryString, function(err, rows, fields, res) {
if (err) throw err;
else{
for (var i in rows) {
res.write(rows[i].title);
console.log(rows[i].creator);
}
}
});
}
You should be careful about "res" variable
function showBets(res1){
connection.query(queryString, function(err, rows, fields, res2) {
if (err) throw err;
else{
for (var i in rows) {
res1.write(rows[i].title);
console.log(rows[i].creator);
}
}
});
res1 and res2 are difference.
Fixed it by doing this:
function showBets(res) {
var queryString = 'SELECT * FROM bets';
connection.query(queryString, [], function(err, rows) {
if (err) {
console.log("aa: " + err);
throw err;
}
rows.forEach(function(row) {
res.write(row.creator);
console.log(row.creator);
});
res.end();
});
}
I keep getting this error (after a certain amount of time) when i refresh the my 'members area' after login. I use response.redirect to redirect to the area (success) or back to sign in form (error). How can i fix this?
app.get('/sellers/login', function(request, response) {
if(request.session.sellerId){
response.redirect( '/sellers/area?logged_in=true');
}
else{
response.render('pages/sellers-login');
}
});
app.post('/authenticate', function(request, response) {
if(request.session.sellerId){
response.redirect('/area?logged_in=true');
}
else{
db.authenticate(request.body.loginid, function(err, results) {
if(err){
response.redirect('/sellers/login?err=1&logged_in=false&type=db');
}
else{
if(results.length >=1){
var hash = results[0]['hash'];
var seller_id = results[0]['id'];
bcrypt.compare(request.body.password, hash, function(err, res) {
if(res){
request.session.sellerId = seller_id;
response.redirect('/sellers/area?logged_in=true');
}
else{
response.redirect('/sellers/login?err=1&logged_in=false&type=pMatch');
}
});
}
else{
response.redirect('/sellers/login?err=1&logged_in=false&type=user');
}
}
});
}
});
app.get('/sellers/area', function(request, response) {
if(request.session.sellerId){
response.render('pages/sellers-area');
}
else{
response.redirect('/sellers/login?not_logged_in=true');
}
});
if(request.session.sellerId){
response.redirect('/area?logged_in=true');
}
db.authenticate(request.body.loginid, function(err, results) {
// ....
});
You send the header when request.session.sellerId evaluates to true by calling the response.redirect, but you continue with the the db.authenticate afterwards.
Inside of that callback you will do another redirect, even when your redirect for that response has already taken place.
Inside of the db.authenticate you have the same problem with the if(err)
EDIT
you need to use an else block (or a return) for both the if (request.session.sellerId) and the if (err) {
if (request.session.sellerId) {
response.redirect('/area?logged_in=true');
} else {
db.authenticate(request.body.loginid, function(err, results) {
if (err) {
response.redirect('/sellers/login?err=1&logged_in=false&type=db');
} else if (results.length >= 1) {
var hash = results[0]['hash'];
var seller_id = results[0]['id'];
bcrypt.compare(request.body.password, hash, function(err, res) {
if (res) {
request.session.sellerId = seller_id;
response.redirect('/sellers/area?logged_in=true');
} else {
response.redirect('/sellers/login?err=1&logged_in=false&type=pMatch');
}
});
} else {
response.redirect('/sellers/login?err=1&logged_in=false&type=user');
}
});
}
I think i've found precisely where the error originates from which lies in the db.authenticate
//db.js
exports.authenticate = function(loginid, callback) {
var sql = "select ...";
pool.getConnection(function(err, connection) {
if(err) {
console.log(err);
callback(true);
return;
}
connection.query(sql, [loginid], function(err, results) {
connection.release();
if(err) {
console.log(err);
callback(true);
return;
}
callback(false, results);
});
connection.on('error', function(err) {
console.log(err);
connection.release();
callback(true);
return;
});
});
};
The connection.on('error',... gets called, so the callback(true) activates causing this error.
I am new to node, and also JavaScript callbacks.
I am trying to check if an account exists in mongo and then 'save it' if it doesn't and return an error if it does.
I am currently trying to figure this out outside of my express app. This is what i have..
var MongoClient = require('mongodb').MongoClient;
MongoClient.connect('mongodb://localhost:27017/main', function (err, db) {
if(err) throw err;
var query = { name : "www.website.com"}
findOne(db, query, function (doc) {
if(doc) {
console.log('account exists');
} else {
console.log('good to go');
}
console.dir(doc);
});
});
var findOne = function (db, query, callback) {
db.collection('accounts').findOne(query, function (err, doc) {
if(err) throw err;
db.close();
callback();
});
}
with the console.dir(doc); above returning as undefined. How do I wait for the findOne to return before using the callback to console.log or save the account?
The reason you are getting undefined is because when you call your callback your are not passing it the doc. That line should look like callback(doc).
Here is an updated version of your code with a few suggestions:
MongoClient.connect('mongodb://localhost:27017/main', function (err, db) {
if(err) throw err;
var query = { name : "www.website.com"}
findOne(db, query, function (err, doc) {
if(err) {
// something went wrong
console.log(err);
return;
}
if(doc) {
console.log('account exists');
console.dir(doc);
} else {
console.log('good to go');
}
});
});
var findOne = function (db, query, callback) {
db.collection('accounts').findOne(query, function (err, doc) {
db.close();
if(err) {
// don't use throw when in async code
// the convention is to call your callback with the error
// as the first argument (notice that I added an argument
// to the definition of your callback above)
callback(err);
}
else {
// call your callback with no error and the data
callback(null, doc);
}
});
}
I'm a begginer in Node.JS and as a first tryout i'm implementing a small url shortening service that will get a request with an id parameter and redirect to the actual url after searching a cassandra database.
Below you can find my implementation.
var reqResponse;
app.get('/r/:id', function(req, res) {
reqResponse = res;
conn.connect(function(err, keyspace) {
if(err){
throw(err);
}
conn.cql(cqlSelectStatement, [req.params.id], { gzip:true }, redirectCallback);
});
});
function redirectCallback (err, results) {
if (err != null) {
//log
} else {
if (results.length > 0) {
results.every(function(row){
reqResponse.writeHead(config.redirectStatus, {
'Location': row[0].value
});
reqResponse.end();
return false;
});
} else {
reqResponse.send("There was a problem!");
return false;
}
}
conn.close();
return true;
}
It works fine, it does the job, but i'm having some doubts about that reqResponse "global" variable. I don't like it there.
Is there a way I could send "res" as a parameter to the redirectCallback function?
Thank you!
Yes there is: Create an anonymous function and use that to pass the parameter:
app.get('/r/:id', function(req, res) {
conn.connect(function(err, keyspace) {
if(err){
throw(err);
}
conn.cql(cqlSelectStatement, [req.params.id], { gzip:true }, function (err, results) { redirectCallback(err, res, results); } );
});
});
And your callback becomes:
function redirectCallback (err, res, results) {