I\'m new to Node.Js and JavaScript web development on the backend. I see that callbacks inside callbacks could be a pain and there are modules to avoid that. One of these mo
Here is the code modified to use async whenever needed.
function check_auth_user(username, password) {
var client = new pg.Client("pg://user:pass@127.0.0.1/database");
async.waterfall([
client.connect,
function(callback) {
client.query('select * from "user" where username = $1 and password = $2', [username, password], callback);
},
function(result, callback) {
if(result.rowCount > 0) {
var res = result.rows[0];
async.series([
function(callback) {
passport.serializeUser(res, function(res, done) {
callback(null, res);
}
},
function(res, callback){
if(res) {
passport.deserializeUser(res, function(res, done) {
callback(null, res);
});
} else {
callback(new Error('SerializeUser failed'));
}
}
], function(err, res) {
if(err) {
callback(err);
} else {
callback(null);
}
});
}
else {
callback(new Error("No result"));
}
}
], function(err, result) {
if(err)
console.err(err);
});
}
Obviously, it does not make the code any more readable. I would suggest additional changes:
These two methods would both take callbacks. Here is a re-write:
// Given a client, queries for user
function retrieveUser( client, username, password, cb) {
client.query('select * from "user" where username = $1 and password = $2', [username, password], function(err, users){
if(err) {
cb(err);
}
else if(users.rowCount < 0) {
cb(new Error("No user found for username ="+username));
}
else {
cb(null, result.rows[0]);
});
}
//Uses passport to serialize/deserializeUser
function passportSerialize(user, cb){
async.series([
function(callback) {
passport.serializeUser(user, function(res, done) {
callback(null, res);
}
},
function(res, callback){
if(res) {
passport.deserializeUser(res, function(res, done) {
if(res) {
callback(null, res);
} else {
callback(new Error('deserializeUser failed'));
}
});
} else {
callback(new Error('SerializeUser failed'));
}
}
], cb);
}
Thus, our main method now becomes:
function check_auth_user(username, password) {
var client = new pg.Client("pg://user:pass@127.0.0.1/database");
async.waterfall([
client.connect,
function(callback) {
retrieveUser(client, username, password, callback);
},
function(user, callback) {
passportSerialize(user, callback);
}
], function(err, result) {
if(err)
console.err(err);
else
console.log("User authenticated, let her in");
});
}
I hope you can see how this is much much better.