Reputation: 986
i have made an event listener for my server which listens for when someone is trying to log on, so i do an sql query and then if the info matches, it logs them on. problem is, its testing if the info matches before it runs the query so it will always return false. here is my code
player.on('checkLogin', function(data)
{
var logIn = "";
connection.query({
sql: "SELECT * FROM users WHERE username = ?",
values: [data.user] },
function(error, results, fields)
{
if (error)
{
console.log(error);
}
if(results)
{
var pass = "";
for (i = 0; i < results.length; i++)
{
pass = (results[i].password);
}
var input = crypto.createHash('md5').update(data.pass).digest("hex");
if (pass == input)
{
logIn = true;
}
}
});
if (logIn == true)
{
this.em.emit('login',
{
id: player.playerid
});
}
}.bind(this));
I heard promises will fix this but is there any easy way around this?, thanks in advance
Upvotes: 0
Views: 428
Reputation: 12683
The issue you have is your if(login == true)
is outside of the completion handlers of the query.
Move the if(logIn == true)
into your completion handler.
player.on('checkLogin', function(data)
{
var logIn = "";
connection.query({
sql: "SELECT * FROM users WHERE username = ?",
values: [data.user] },
function(error, results, fields)
{
if (error)
{
console.log(error);
}
if(results)
{
var pass = "";
for (i = 0; i < results.length; i++)
{
pass = (results[i].password);
}
var input = crypto.createHash('md5').update(data.pass).digest("hex");
if (pass == input)
{
logIn = true; //<-- could just handle it here.
}
if (logIn == true) //<-- moved inside completion handler
{
//log on
}
}
});
}.bind(this));
Now the reason it is being called is your connection.query
runs asynchronously which is why the function
handler is used. Code outside the completion handler will be run immediately.
EDIT from Additional Changes
Based on your changes your this
scope will be changed when moved inside the completion handler function. To get a reference back you will need a reference to the player
scope (assuming that is what this
is). So that can be handled simply by creating a variable of this as var that = this;
at the top of your checklogin
function. Something like:
player.on('checkLogin', function(data)
{
var that = this; //create a variable to store the scope (this)
var logIn = "";
connection.query({
sql: "SELECT * FROM users WHERE username = ?",
values: [data.user] },
function(error, results, fields)
{
if (error)
{
console.log(error);
}
if(results)
{
var pass = "";
for (i = 0; i < results.length; i++)
{
pass = (results[i].password);
}
var input = crypto.createHash('md5').update(data.pass).digest("hex");
if (pass == input)
{
logIn = true; //<-- could just handle it here.
}
if (logIn == true) //<-- moved inside completion handler
{
//log on
that.em.emit('login', //<-- reference `that` not `this`
{
id: player.playerid
});
}
}
});
}.bind(this));
Upvotes: 1