So.. I'm having the hardest time learning how to Promise.
I'm using bluebird
(https://github.com/petkaantonov/bluebird) as suggested to me -- in order to tame my callback hell I've been getting. Example:
function login(req,res,con,mysql,P) {
var ref = undefined;
con.getConnection(function(err,connection) {
if (err) console.log("Get Connection Error.. "+err);
con.query('SELECT password,id FROM player WHERE name='+mysql.escape(req.body.user),function(err,rows,fields) {
if (err) throw err;
if (!rows[0]) {
res.send({
"msg":"Your username and or password was incorrect.",
"flag":true,
"title":": Login Failed"
});
}
if (rows[0].password !== "undefined") {
if (hash.verify(req.body.pass,rows[0].password)) {
req.session.loggedIn = true;
req.session.user = rows[0].id;
ref = new P(rows[0].id,con,req);
res.send({
"msg":"You have logged in!",
"flag":false,
"title":": Logged In"
});
} else {
res.send({
"msg":"Your username and or password was incorrect.",
"flag":true,
"title":": Login Failed"
});
}
}
});
connection.release();
});
console.log(ref);
return ref;
}
It's nasty, it's full of callbacks, and the function returns ref
before the query callback is finished executing.
Solution: promises!
I tried to convert my function using the quick start.. so I promisefyAll
'd my mysql
module before creating the connection:
var mysql = require("mysql");
var Promise = require("bluebird");
Promise.promisifyAll(mysql);
And I wrote my function as follows:
function login(req,res,con,mysql,P) {
var ref = undefined;
Promise.promisify(con.getConnection)().then(function(connection) { //updated line returns error no method promisify. Bluebird v. 1.1.1
con.query('SELECT password,id FROM player WHERE name='+mysql.escape(req.body.user)).then(function(rows,fields) {
if (hash.verify(req.body.pass,rows[0].password)) {
req.session.loggedIn = true;
req.session.user = rows[0].id;
ref = new P(rows[0].id,con,req);
res.send({
"msg":"You have logged in!",
"flag":false,
"title":": Logged In"
});
} else {
res.send({
"msg":"Your username and or password was incorrect.",
"flag":true,
"title":": Login Failed"
});
}
});
return ref;
});
}
But I keep getting TypeError: Cannot call method 'then' of undefined at Object.login (/var/www/post/posts.js:36:22)
And
TypeError: undefined is not a function at Pool.<anonymous> (/var/www/node_modules/mysql/lib/Pool.js:53:14)
Errors. Can somebody help me understand how to implement promises for querying my database (correctly)?
Edit (post answer acceptance:): here is how I call the login function:
app.post("/login",function(req,res) {
Player = post.login(req,res,con,mysql,p);
console.log(Player); // logs [Object object]
}); //inside the login function, it logs the object like it should
Apologize for breaking the promise. Being overly defensive or distancing yourself from the situation makes it sound like this type of promise-breaking could happen at any time because you are not in control. Instead, be accountable and reveal what you plan to do differently in the future.
IS IT EVER OKAY to break a promise? Generally speaking, no. A promise changes reality by introducing an ingredient that wouldn't exist except for the promise.
As you make those promises, you build momentum. As you break those promises, you lead yourself to the path of inertia, one of the main negative consequences of continued broken promises. Let's take a look at how people end up at the point of inertia, totally stuck.
Give your friend the benefit of the doubt, suggests the Southam Consulting team in “The Ten Secrets to Managing Broken Promises, Violated Expectations, and Bad Behavior.” State the facts as you see them, such as “The paper you promised to help me with is still unfinished," or "You promised you'd come to my dance ...
When you promisify a prototype, the promise returning methods will have *Async suffix
The idea of promisification is to pretend as if the library was designed to return promises to begin with. You should not call promisify in application code during runtime, but in your appliation bootstrap init code or similar.
var mysql = require("mysql");
var Promise = require("bluebird");
//Only need to be called once per application so probably not here
Promise.promisifyAll(require("mysql/lib/Connection").prototype);
Promise.promisifyAll(require("mysql/lib/Pool").prototype);
function login(req,res,con,mysql,P) {
return con.getConnectionAsync().then(function(connection) {
return connection.queryAsync('SELECT password,id FROM player WHERE name='+
mysql.escape(req.body.user)).spread(function(rows, fields) {
if (hash.verify(req.body.pass,rows[0].password)) {
req.session.loggedIn = true;
req.session.user = rows[0].id;
var ref = new P(rows[0].id,con,req);
res.send({
"msg":"You have logged in!",
"flag":false,
"title":": Logged In"
});
return ref;
} else {
res.send({
"msg":"Your username and or password was incorrect.",
"flag":true,
"title":": Login Failed"
});
}
}).finally(function() {
connection.release();
});
});
}
A future version will have much better resource management and you will be able to do:
function login(req,res,con,mysql,P) {
return Promise.using(con.getConnectionAsync(), function(connection) {
return connection.queryAsync('SELECT password,id FROM player WHERE name='+
mysql.escape(req.body.user));
}).spread(function(rows, fields) {
if (hash.verify(req.body.pass,rows[0].password)) {
req.session.loggedIn = true;
req.session.user = rows[0].id;
var ref = new P(rows[0].id,con,req);
res.send({
"msg":"You have logged in!",
"flag":false,
"title":": Logged In"
});
return ref;
} else {
res.send({
"msg":"Your username and or password was incorrect.",
"flag":true,
"title":": Login Failed"
});
}
});
}
How to use the result:
app.post("/login",function(req,res) {
post.login(req,res,con,mysql,p).then(function(Player) {
});
})
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With