I'm trying to check user name and password (which I'm getting via post) and if it correct, response with the user page.
for some reason I'm always fail (although I know the user and pass are correct):
app.post("/loginDetials", function(req, res) {
var userName = req.body.userName;
var passw = req.body.passw;
if(req.body.userName && req.body.passw)
{
console.log('Checkking userName: ' + userName + ' password: ' + passw);
var db = new sqlite3.Database('usersDataBase');
db.all("SELECT * FROM usersTable where (userName==?) AND (password==?)", function(err,rows){
if (err)
{
console.log('Error: ' + err);
}
else
{
rows.forEach(function (row) {
console.log('Login Succ')
res.sendFile('userSite.html', {root: __dirname })
});
}
});
db.close();
}
console.log('Login Fail')
res.sendFile('main.html', {root: __dirname })
});
What am I doing wrong ?
And is this the correct way to verify details ?
You have some async code and other flow problems with your code.
You are actually sending twice your response and you close the database before the query has been executed.
Problem with calling twice res.send
var userName = req.body.userName;
var passw = req.body.passw;
if(req.body.userName && req.body.passw) {
/** Some logic */
res.send(...);
}
res.send(...);
So you see res.send is called twice if you have supplied userName and passw query.
Problem with async closing db connection
In JavaScript we have async functions which don't stop the flow of the program and rely on callbacks. db.all is such a function, which you call and immediately after that you call db.close()
var db = new sqlite3.Database('usersDataBase');
db.all("SELECT * FROM usersTable where (userName==?) AND (password==?)", function(err,rows){
// You need to move your `db.close()` inside the callback
// in order to close the database when the query has ended
db.close();
if (err)
{
console.log('Error: ' + err);
}
else
{
rows.forEach(function (row) {
console.log('Login Succ')
res.sendFile('userSite.html', {root: __dirname })
});
}
});
// db.close(); <-- commented out.
Related
I am running a Node.js/Express application. Within this code I have a function which accepts data from a 'form' to register a 'new user'. This function takes the input user information and performs a few tasks, such as checking for illegal characters, checking to determine if the input email ALREADY exists in the database, 'hashes' the input name and password, and finally writes to a (PostGres) database the 'new' user information. All this code is formatted in a 'promise tree' so each task is done sequentially, one after the other. The code is as follows:
//server.js
const db = require('./routes/queries');
const traffic = require('./routes/traffic');
...
app.post('/_register', function(req, res) {
if (!req.body) {
console.log('ERROR: req.body has NOT been returned...');
return res.sendStatus(400)
}
var newHash, newName;
var newToken = shortid.generate();
var client = req.body.user_email;
var creds = req.body.user_password;
var firstname = req.body.user_name;
db.sanitation(client, creds, firstname).then(function (direction) {
console.log('USER-SUPPLIED DATA HAS PASSED INSPECTION');
return db.checkEmail(client); //<==call database query here to check for existing email
}).then(function (founduser) {
if (typeof foundUser != "undefined") {
console.log('HEY THERE IS ALREADY A USER WITH THAT EMAIL!', foundUser);
if (founduser.status === "active") {res.redirect('/client_login'); }
return Promise.reject("Email EXTANT"); //break out of promise chain...to prevent additional code processing below...
} else {
console.log('USER EMAIL NOT CURRENTLY IN DATABASE...THEREFORE IT IS OK...UNDEFINED!!!'); //appears in log
return traffic.hashPassword(creds); //hash password and continue processing code below...
} //'foundUser' is 'undefined'...OR NOT...
}).then(function (hashedPassword) {
console.log('PASSWORD HASHED'); //does NOT appear in logs
newHash = hashedPassword;
return traffic.hashUsername(firstname);
}).then(function (hashedName) {
console.log('NAME HASHED'); //does NOT appear in logs
newName = hashedName;
return db.createUser(newName, client, newHash, newToken);
}).then(function (data) {
console.log('REGISTERED A NEW CLIENT JOIN...!!!');
},
function(error) {
console.log('USER REGISTRATION FAILURE...'); //<==THIS MESSAGE SHOWS IN 'LOGS'...WHY???
}
).then(function () {
res.redirect('/landing'); //this page re-direction DOES occur...
}).catch(function (err) {
console.log('THERE WAS AN ERROR IN THE SEQUENTIAL PROCESSING...' + error);
res.redirect('/');
});
}); //POST 'register' is used to register NEW users...
Here is my issue. When this code is executed and the user email is NOT already in the database, in my logs I see the message "USER EMAIL NOT CURRENTLY IN DATABASE...THEREFORE IT IS OK...UNDEFINED!!!" ...this is to be expected since the email is not in the database. From this point the code should continue to process, first 'hashing' the user password and continuing down the 'promise tree'.
In fact what does happen is that it seems the 'hashing' of the user password and name do NOT happen...since I see no log messages to indicate they executed. Instead I see the following message in the log, "USER REGISTRATION FAILURE...", which indicates a 'failure' (rejection) of the code to write to the database.
My question is WHY does the part where I check for an 'undefined' response from the "checkEmail" function NOT seem to execute my code therein (the 'return traffic.hashPassword(creds);' function) and then subsequently throw the 'reject' later in the code in the 'return db.createUser'.
This makes absolutely no sense to me. It seems as though the 'undefined' response from checking for an extant user email in the database prevents execution of parts of the remainder of the code, and inexplicably throws a 'rejection' of the database writes.
This is killing me. It has taken about a week of my time and I seem no closer to resolving this issue. If my code to handle the 'undefined' return from the 'checkEmail' call is somehow incorrect can somebody demonstrate a proper way to perform this? Any advice is HUGELY appreciated.
I have made comment notations in my code above to illustrate what is and what is not displaying in my logs
UPDATE:
Based upon the kind feedback I have received, I have re-written the code above using two different approaches. Here is the first:
app.post('/register', function(req, res) {
if (!req.body) {
console.log('ERROR: req.body has NOT been returned...');
return res.sendStatus(400)
}
var newHash, newName;
var client = req.body.client_email;
var creds = req.body.client_password;
var newToken = shortid.generate();
var firstname = req.body.client_name;
try {
const users = db.checkEmail(client);
users.then(function(result) {
console.log('FINAL RESULT ROWS ARE: ' + result.rows)
if (typeof result.rows != "undefined") {
console.log('HEY THERE IS ALREADY A USER WITH THAT EMAIL!');
if (result.status === "active") {
console.log("Email EXTANT");
return res.redirect("/client_login");
} //"active"
} else {
console.log('USER EMAIL NOT CURRENTLY IN DATABASE...THEREFORE IT IS OK...');
return traffic.hashPassword(creds);
} //'result.rows' is 'undefined'...OR NOT...
})
.then(function(result) {
console.log('PASSWORD HASHED');
console.log(result);
newHash = result;
return traffic.hashUsername(firstname);
})
.then(function(result) {
console.log('NAME HASHED');
newName = result;
return db.createUser(newName, client, newHash, newToken);
})
.then(function(result) {
console.log('REGISTERED A NEW CLIENT JOIN...!!!');
})
.then(function(result) {
res.redirect('/landing'); //route to 'landing' page...
});
} catch(err) {
// handle errors
console.log('ERROR IN TRY/CATCH IS: ' + err);
}
}); //POST 'register' is used to register NEW clients...
This code is functional, however it always reports the 'email' is NOT being in the database...even when in fact it is. Here is the log of the output:
FINAL RESULT ROWS ARE: undefined
USER EMAIL NOT CURRENTLY IN DATABASE...THEREFORE IT IS OK...
PASSWORD HASHED
$2b$10$vW3.YkPyoB9MG5k9qiGreOQC05rWsEIO6i.NkYg6oFqJ8byNjp.iu
NAME HASHED
REGISTERED A NEW CLIENT JOIN...!!!
Here is the second block of code, using an 'async/await' in the function:
app.post('/register', async function(req, res) {
if (!req.body) {
console.log('ERROR: req.body has NOT been returned...');
return res.sendStatus(400)
}
var newHash, newName;
var client = req.body.client_email;
var creds = req.body.client_password;
var newToken = shortid.generate();
var firstname = req.body.client_name;
try {
//const direction = await db.sanitation(client, creds, firstname);
const founduser = await db.checkEmail(client);
console.log('founduser ROWS ARE: ' + founduser.rows)
if (typeof foundUser != "undefined") {
console.log("HEY THERE IS ALREADY A USER WITH THAT EMAIL!", foundUser);
if (founduser.status === "active") {
console.log("Email EXTANT");
return res.redirect("/client_login");
}
} //NOT "undefined"
console.log("USER EMAIL NOT CURRENTLY IN DATABASE...THEREFORE IT IS OK...!!!");
} catch (err) {
console.log("THERE WAS AN ERROR IN THE SEQUENTIAL PROCESSING OF THE TRY STATEMENT..." + err);
return res.redirect("/");
}
}); //POST 'register' is used to register NEW clients...
This code is ALSO functional, however as with the first block of code it always reports the 'email' is NOT being in the database...even when in fact it is. Here is the log of the output:
USER EMAIL NOT CURRENTLY IN DATABASE...THEREFORE IT IS OK...!!!
Based upon these results, it is my belief either block of code is likely functional...and the reason all executes report the email as 'undefined' (even when it already exists in the database) is because of the "checkEmail" function. I probably have it incorrectly written to properly return an 'async' result. Here is that code:
const Pool = require('pg').Pool;
const pool = new Pool({
user: 'postgres',
host: '127.0.0.1',
database: 'myDB',
password: 'password',
})
const checkEmail = async function(mail) {
return new Promise(function(resolve, reject) {
pool.query('SELECT * FROM clients WHERE email = $1', [mail], function(error, results) {
if (error) {
reject(new Error('Error processing a database check for email!'));
} else {
resolve(results.rows);
}
console.log('checkEmail mail: ' + mail);
console.log('checkEmail results.rows: ' + results.rows);
}) //pool.query
}); //new promise
}
Is somebody able to confirm my suspicion that BOTH of the blocks of "try/catch" code above are written correctly...and the problem with the call always returning "undefined" lies in the "checkEmail" function? And, if that is the case...perhaps suggest how I need to correct that "checkEmail" function to properly find the existing email in the database when necessary. I am not terribly familiar with usage of 'async' functions and have never attempted their usage in a promise to query a database. I thank you in advance for any reply.
UPDATE/SOLUTION:
When I first wrote the "checkEmail" promise function, I assumed it would 'resolve' if a matching email was discovered in the database...and 'reject' if it was not. What I am experiencing is that the function always 'resolves', even if the email is not located in the database. Therefore I found usage of the 'object.keys' method to be useful to check if in fact some data returned from the function. Using this I can write code that now seems to be properly functioning. Here is my current "checkEmail" function:
//queries.js
const checkEmail = async function(mail) {
return new Promise(function(resolve, reject) {
pool.query('SELECT * FROM clients WHERE email = $1', [mail], function(error, results) {
if (error) {
reject(new Error('Error processing a database check for email!'));
} else {
resolve(results.rows);
}
console.log('checkEmail mail: ' + mail);
console.log('checkEmail results.rows: ' + results.rows);
}) //pool.query
}); //new promise
}
module.exports = {
...
checkEmail,
...
}
and my promise tree:
//server.js
app.post('/register', function(req, res) {
if (!req.body) {
console.log('ERROR: req.body has NOT been returned...');
return res.sendStatus(400)
}
var client = req.body.client_email;
var creds = req.body.client_password;
var newToken = shortid.generate();
var firstname = req.body.client_name;
db.sanitation(client, creds, firstname)
.then(function (direction) {
console.log('Result direction Object.keys from SANITATION: ', Object.keys(direction).length);
console.log('USER-SUPPLIED DATA HAS PASSED INSPECTION');
return db.checkEmail(client); // <==call database query here to check for existing email for existing email
})
.then(function (founduser) {
console.log('foundUser matching email in database: ', founduser);
console.log('foundUser Object.keys matching email in database: ', Object.keys(founduser).length);
if (Object.keys(founduser).length > 0) {
console.log('EMAIL IS EXTANT IN DATABASE ALREADY!');
if (founduser.length) {console.log('foundUser LENGTH matching email in database: ', founduser.length);}
if (founduser[0].status === 'active') {
console.log('USER-SUPPLIED EMAIL EQUALS THAT OF AN ACTIVE USER');
throw new Error('active'); //break out of promise chain...to prevent additional code processing below...
} else {
console.log('USER-SUPPLIED EMAIL APPEARS IN THE DATABASE');
throw new Error('Email EXTANT'); //break out of promise chain...to prevent additional code processing below...
} //founduser[0].status
} //founduser.length EXCEEDS "0"
if (Object.keys(founduser).length === 0) {
console.log('EMAIL IS NOT PRESENT IN THE DATABASE!');
return traffic.hashPassword(creds); // hash password and continue processing code below...
} //founduser.length EQUALS "0"
})
.then(function (hashedPassword) {
console.log('PASSWORD HASHED');
return traffic.hashUsername(firstname)
.then(function (hashedName) { // nested to keep hashedPassword within scope
console.log('NAME HASHED');
return db.createUser(hashedName, client, hashedPassword, newToken)
.catch(function (error) { // nested in order to catch only an error arising from db.createUser(), (not necessary other than to log out an error message).
console.log('USER REGISTRATION FAILURE...'); // this message will appear only if db.createUser() fails
throw error; // RETHROW error in order to jump to the terminal catch (and hit the `default` case).
});
});
})
.then(function (data) {
console.log('REGISTERED A NEW CLIENT JOIN...!!!');
res.redirect('/landing'); // success
})
.catch(function (err) {
switch(err.message) {
case 'active':
res.redirect('/client_login');
break;
case 'Email EXTANT':
res.redirect('/client_login');
break;
default: // all unexpected errors
console.log('THERE WAS AN ERROR IN THE SEQUENTIAL PROCESSING... ' + err.message);
res.redirect('/');
}
});
}); //POST 'register' is used to register NEW clients...
I would like to thank those individuals that responded to this post. I am greatly appreciative of their time and suggestions that allowed me to get to this point of what is now evidently functional code. Those replies, in addition, are very instructive and I have learned some new techniques from the help I have received.
I wonder if you might be missing one or more of the following basic principles governing errors in promise chains:
if an Error is caught and you want it not to be marked as handled (eg if you catch an Error just to log it) then you must rethrow the error (or throw an Error of your own) in order to proceed down the promise chain's error path.
if an Error is caught and not rethrow then promise chain will proceed down its success path. If a value is not explicitly returned, then undefined will be delivered to the next step.
a naturally occuring or deliberately thrown Error will propagate to the next qualifying .catch().
a .catch() in a given chain will catch any earlier error, not just one arising from the immediately preceeding step.
a .catch() written in the form .then(successHander, errorHandler) will catch errors from preceding steps in the chain but not from the successHander. This can be useful (but not here).
a .catch() can often be made "private" (ie specific to a particular async step) by nesting it within the main chain. This avoids catching errors arising from earlier in the chain.
within a promise chain throwing an error is more economical than return Promise.reject(...).
You can embed the redirects in the chain however I suggest that it's cleaner to throw errors and branch in the terminal .catch() (eg with a switch/case structure).
You might end up with something like this (plenty of comments in code) ...
//server.js
const db = require('./routes/queries');
const traffic = require('./routes/traffic');
...
app.post('/_register', function(req, res) {
if (!req.body) {
console.log('ERROR: req.body has NOT been returned...');
return res.sendStatus(400)
}
// var newHash, newName; // not needed
var newToken = shortid.generate();
var client = req.body.user_email;
var creds = req.body.user_password;
var firstname = req.body.user_name;
db.sanitation(client, creds, firstname)
.then(function (direction) {
console.log('USER-SUPPLIED DATA HAS PASSED INSPECTION');
return db.checkEmail(client); // <==call database query here to check for existing email
})
.then(function (founduser) {
if (typeof foundUser != "undefined") { // not a particularly good test, maybe if(foundUser) {...} would be better?
console.log('HEY THERE IS ALREADY A USER WITH THAT EMAIL!', foundUser);
if (founduser.status === 'active') {
throw new Error('active'); // break out of promise chain...to prevent additional code processing below...
} else {
throw new Error('Email EXTANT'); // break out of promise chain...to prevent additional code processing below...
}
} else {
console.log('USER EMAIL NOT CURRENTLY IN DATABASE...THEREFORE IT IS OK...UNDEFINED!!!'); // appears in log
return traffic.hashPassword(creds); // hash password and continue processing code below...
}
})
.then(function (hashedPassword) {
console.log('PASSWORD HASHED');
return traffic.hashUsername(firstname)
.then(function (hashedName) { // nested to keep hashedPassword within scope
console.log('NAME HASHED');
return db.createUser(hashedName, client, hashedPassword, newToken)
.catch(function (error) { // nested in order to catch only an error arising from db.createUser(), (not necessary other than to log out an error message).
console.log('USER REGISTRATION FAILURE...'); // this message will appear only if db.createUser() fails
throw error; // RETHROW error in order to jump to the terminal catch (and hit the `default` case).
});
});
})
.then(function (data) {
console.log('REGISTERED A NEW CLIENT JOIN...!!!');
res.redirect('/landing'); // success
})
.catch(function (err) {
// Suggest you perform all error case redirects here, depending on which error occurred.
// May not be 100% correct but you get the idea.
switch(err.message) {
case 'active':
res.redirect('/client_login');
break;
case 'Email EXTANT':
default: // all unexpected errors
console.log('THERE WAS AN ERROR IN THE SEQUENTIAL PROCESSING... ' + err.message);
res.redirect('/');
}
});
}); // POST 'register' is used to register NEW users...
I think the problem is return Promise.reject("Email EXTANT");. If you want to break the execution, you can just use return res instead.
Try the example below with asyn/await approach.
Edit: add checkEmail updates
//server.js
const db = require("./routes/queries");
const traffic = require("./routes/traffic");
app.post("/_register", async function (req, res) {
if (!req.body) {
console.log("ERROR: req.body has NOT been returned...");
return res.sendStatus(400);
}
var newToken = shortid.generate();
var client = req.body.user_email;
var creds = req.body.user_password;
var firstname = req.body.user_name;
try {
const direction = await db.sanitation(client, creds, firstname);
const foundusers = await db.checkEmail(client);
if (foundusers.length) {
console.log(
"HEY THERE IS ALREADY A USER WITH THAT EMAIL!",
foundusers[0]
);
if (foundusers[0].status === "active") {
console.log("Email EXTANT");
return res.redirect("/client_login");
}
}
console.log(
"USER EMAIL NOT CURRENTLY IN DATABASE...THEREFORE IT IS OK...UNDEFINED!!!"
);
const hashedPassword = await traffic.hashPassword(creds);
console.log("PASSWORD HASHED");
const hashedName = await traffic.hashUsername(firstname);
await db.createUser(hashedName, client, hashedPassword, newToken);
console.log("REGISTERED A NEW CLIENT JOIN...!!!");
return res.redirect("/landing");
} catch (err) {
console.log("THERE WAS AN ERROR IN THE SEQUENTIAL PROCESSING..." + err);
return res.redirect("/");
}
});
I update the checkEmail function.
Reminder: you should create a db.js to export the pool instead of create a pool inside the checkEmail.js file. Then when you need to query in other function, they can import the pool from it instead of recreateing a new pool.
const Pool = require("pg").Pool;
const pool = new Pool({
user: "postgres",
host: "127.0.0.1",
database: "myDB",
password: "password",
});
export const checkEmail = async function (mail) {
try {
const res = await pool.query("SELECT * FROM clients WHERE email = $1", [
mail,
]);
console.log(res);
return res.rows;
} catch (err) {
throw err;
}
};
I'm new to Node.js and am trying to pass some data from my DB model back to the router but I'm unable to find a solution. I have the following route file that makes a call to model:
Route file:
var express = require('express');
var router = express.Router();
var db = require('../db');
var customers = require('../models/customers');
db.connect(function(err) {
if (err) {
console.log('Unable to connect to MySQL.')
process.exit(1)
}
});
router.post('/', function(req, res) {
customers.checkPassword(req.body.cust_id, req.body.password);
res.sendStatus(200);
});
Model file:
var db = require('../db.js');
module.exports.checkPassword = function(cust_id, password) {
var sql = "SELECT Password FROM Shop.customers WHERE ID =" + cust_id;
db.get().query(sql, function (err, res, fields) {
result = res[0].Password;
if (err) throw err
});
};
My question is: how could I pass the queried result Password back to my Route file so that I can do this:
console.log('Password is', result);
I appreciate any help on this.
I'd use a promise
Model file
module.exports.checkPassword = function(cust_id, password) {
return new Promise(function(resolve, reject) {
const sql = "SELECT Password FROM Shop.customers WHERE ID =" + cust_id;
db.get().query(sql, function (err, res, fields) {
if (err) return reject(err)
result = res[0].Password;
return resolve(result);
});
});
};
Route file
var express = require('express');
var router = express.Router();
var db = require('../db');
var customers = require('../models/customers');
db.connect(function(err) {
if (err) {
console.log('Unable to connect to MySQL.')
process.exit(1)
}
});
router.post('/', function(req, res) {
customers.checkPassword(req.body.cust_id, req.body.password)
.then((result) => {
// DO: something with result
res.status(200).send();
})
.catch(console.log); // TODO: Handle errors
});
With async/await
router.post('/', async function(req, res) {
try {
const result = await customers.checkPassword(req.body.cust_id, req.body.password)
// DO: something with the result
} catch (e) {
console.log(e); // TODO: handle errors
} finally {
res.status(200).send();
}
});
I assume console.log('Password is', result); is just for test prupose, obviously you should never log a password! Also I suggest to move the callbabck of the routes do a different module, to improve code redability.
You might also find useful promise-module module on npm, basically a promise wrapper around mysql.
You can delegate the credential control to another function in your DB file where you can decide on what kind of data you want to return on success and failure to find such data. Then you can access it from where you are calling it.
rooms.js -> controller class for rooms endpoint
router.get('/:roomid/fight/verify', function(req, res) {
roomModel.authenticateUserForFight(req.params.roomid, req.query.otp, res);
});
roomModel -> model class for rooms
//authenticate user based on otp provided on client side
exports.authenticateUserForFight = function(roomid, otp, res) {
db.query('select * from room where roomid=?', [roomid], function(error, rows) {
if (rows.length == 0) {
console.log("otp does not exist in db for room:" + roomid);
} else if (rows.length == 1) {
var otpInDb = rows[0].otp.toString();
if (otp == otpInDb) {
console.log("User is authorised");
res.status(200);
res.send("User is authorised");
} else {
console.log("User is unauthorised");
res.status(401);
res.send("User not authorised");
}
}
});
}
This piece of code works fine but is there a better way to send response to client instead of passing res object to model class and setting the status and response message there ? The reason i am passing the res object is because doing res.status and res.send in controller is giving issues as the db call is asynchronous. Suggest some better practices to handle these kind of situtations.
You are right. You should not pass the res object. Its a debugging nightmare if there is more than one place from where the function can exit. Its far better that the subsequent functions return the value and the controller responds to the status.
You can simply create a callback method which will be called once the async db query is completed. Something like this
router.get('/:roomid/fight/verify', function(req, res) {
const callback = (status, message) => {
res.status = status
res.send(message);
}
roomModel.authenticateUserForFight(req.params.roomid, req.query.otp, callback);
});
and the main function can just call this function
//authenticate user based on otp provided on client side
exports.authenticateUserForFight = function(roomid, otp, callback) {
db.query('select * from room where roomid=?', [roomid], function(error, rows) {
if (rows.length == 0) {
console.log("otp does not exist in db for room:" + roomid);
} else if (rows.length == 1) {
var otpInDb = rows[0].otp.toString();
if (otp == otpInDb) {
console.log("User is authorised");
callback(200, 'user authorized');
} else {
console.log("User is unauthorised");
callback(401, 'user not authorized');
}
}
});
}
this is the updated code
if (otp == otpInDb) {
console.log("User is authorised");
res.json({
status:200,
message:"user authorized"
})
} else {
res.json({
status:401,
message:"user not authorized"
})
}
It is always better to send your response in envelope. and I can see you are using String like queries. Use orm wrapper like sequelize to prevent SQL injection attacks
I am creating a 'refresh data' function in Node and I cannot figure out where to place the callbacks and returns. The function continues to run. Below is a list of things the function should do. Could someone help out?
Check if a user has an api id in the local MongoDB
Call REST api with POST to receive token
Store token results in a MongoDB
Terminate function
./routes/index.js
router.post('/refresh', function(req, res) {
var refresh = require('../api/refresh');
refresh(req, function() { return console.log('Done'); });
});
../api/refresh.js
var callToken = require('./calltoken');
var User = require('../models/user'); // Mongoose Schema
module.exports = function(req, callback) {
User.findOne( {'username':req.body.username}, function(err, user) {
if(err) { console.log(err) }
if (user.api_id == 0) {
callToken.postToken(req.body.username, callback);
} else { // Do something else }
});
};
./calltoken.js
var request = require('request');
var Token = require('../models/token'); // Mongoose Schema
module.exports = {
postToken: function(user, callback) {
var send = {method:'POST', url:'address', formData:{name:user} };
request(send, function(err, res, body) {
if(err) { console.log(err) }
if (res.statusCode == 201) {
var newToken = new Token();
newToken.token = JSON.parse(body).access_token['token'];
newToken.save(function(err) {
if(err) { console.log(err) }
return callback();
});
}
});
}
};
I'm not an expert in Express but everywhere in you code in lines with if(err) { console.log(err) } you should stop execution (maybe of course not - up to you app) and return 400 or 500 to client. So it can be something like
if(err) {
console.log(err);
return callback(err); // NOTICE return here
}
On successful execution you should call return callback(null, result). Notice null as a first argument - it is according nodejs convention (error always goes as first argument).
i am new in node.js and postgresql. am allready connected with postgres db and execute some test code. after am going to use prepared statements.am create a sample login script. if user exist it return username else return message "invalid username or password". if username and password is correct,it return username. but no data will present , then could not return message. my openion is that , the control will crashed after executing cliend.end() function.
this is my code
UserLogin.get = function(userName, callBack) {
pg.connect(pgConString, function(err, client, done) {
if (err) {
callBack("DB connection failed. " + err, null);
return;
}
var selectQuery="SELECT * from " + TABLE + " WHERE userName=($1)";
var query=client.query({
text:selectQuery,
values:[userName],
name:"selectQuery"});
query.on("error", function (error) {
callBack("DB fetch failed. Error Message: " + err, null);});
query.on('row', function(row) {
callBack(null, row);});
query.on("end", function (result) {
client.end();
return;
});
});
}
if row is empty, not return to callback. if row_result is not empty, its working fine.. How...???? any idea...???
finally i got the answer. thanks for u r supports
UserLogin.get = function(userName, callBack) {
pg.connect(pgConString, function(err, client, done) {
if (err) {
callBack("DB connection failed. " + err, null);
return;
}
var selectQuery="SELECT * from " + TABLE + " WHERE userName=($1)";
var query=client.query({
text:selectQuery,
values:[loginId],
name:"selectQuery"});
query.on("error", function (error) {
callBack("DB fetch failed. Error Message: " + err, null);return;});
query.on('row', function(row,result) {
result.addRow(row);
});
query.on('end', function (result) {
callBack(null,result.rows);
client.end();
return;
});
});
}
in my old code, callback will be called everytime the query fetches 1 row from the database. am just changed the logic
Your code
query.on('row', function(row) {
callBack(null, row);
});
means that the callback will be called everytime the query fetches 1 row from the database. In the case when the query has 0 results, the callback will never be called.