I am new to node.js, and I am starting with login and signUp implementation, and I have just found that my database Query of MySQL failed to execute in sequence. So what I do is to find does username match exisiting usernames in database, and invitation codes, if there exist, I will send my JSON file with property true, otherwise false, but I have just found, the json file is sent before the database query is finished, so that even if user name matched, the response property is still set to false. I tried async and sync but I still have trouble understanding and fixing my error, can someone please help me on fix or a better alternative implementation in this case? Thank you!!
Here is my code:
// build up connection to db
const con = mysql.createConnection({
host: 'localhost',
user: 'root',
password: 'pwd',
database: 'test'
});
// async function search
async function dbFind(db, dbName, attribute, value) {
let users;
try{
console.log(`11111111111111`)
const users = await db.promise().query(`SELECT EMAIL_ADRESS FROM ${dbName} WHERE ${attribute} = ?`, [value]);
// console.log(`users: ${users}`)
if (users) {
return users;
} else {
return null;
}
} catch (err){
console.log(err)
}
}
// parse the json file from front-end and save it in variable data
app.post('/API/user/registration', function(req,res){
con.connect((err) => {
if(err){
console.log(err);
return;
}
console.log('Connection established');
});
var username = req.body.username;
var password = req.body.password;
var invicode = req.body.invitation_code;
var name = req.body.name;
console.log('reqeust ' + req.body)
// variable initialization
var invitationCodeMatched = false;
var role = 'student';
const uid = uuid.v4();
var verifyToken = uuid.v1()
var flag = true;
// // check if the username have already been registered isRegistered
if (dbFind.sync(con, 'login_Authentication', 'EMAIL_ADRESS', username) != null){
flag = false
} else {
flag = true
}
console.log(`1 ${flag}`)
// check invitation code to see if a user qualify for a TA:
if (dbFind(con, 'invitation_code', 'INVITATION_CODE', invicode) != null){
role = 'TA';
invitationCodeMatched = true
}
console.log(`3 ${invitationCodeMatched}`)
// otherwisr: insert it into te database:
const uLoginAuth = {
USER_ID: uid,
EMAIL_ADRESS: username,
PSWORD:password,
VERIFIED: false,
VERIFYCODE: verifyToken
};
const uInfo = {
USER_ID: uid,
NME: name,
USER_ROLE: role,
EMAIL_ADRESS: username
};
if(flag){
con.query('INSERT INTO login_authentication SET ?', uLoginAuth, (err, res) => {
if(err) throw err;
console.log('Last insert ID:', res.insertId);
});
con.query('INSERT INTO user_info SET ?', uInfo, (err, res) => {
if(err) throw err;
console.log('Last insert ID:', res.insertId);
});
}
con.query('SELECT * FROM user_info', (err,rows) => {
if(err) throw err;
console.log('Data received from Db:');
console.log(rows);
});
con.end((err) => {
// The connection is terminated gracefully
// Ensures all remaining queries are executed
// Then sends a quit packet to the MySQL server.
});
//send json file to the front end
console.log(`2 ${flag}`)
let judge = {
isRegistered: flag,
invitationCodeMatched: invitationCodeMatched
};
res.json(judge);
//If the user has not yet verified:
lib.sendConfirmationEmail(name, username, verifyToken)
});
app.listen(3000)
The output while hearing from request is:
1 false
2 false
and there is no output of 11111111 inside async dbFind function, there is a database match in this scenario, but what it returns is :
{
"isRegistered": false,
"invitationCodeMatched": false
}
which is the default value that is initailized before.
dbFind.sync(). The function you show isdbFind()and because it isasync, it returns a promise which you would need toawaitor use.then()to get its value.db.promise().query()doesn't look correct. What database module from NPM are you using?con.connect()isn't correct either as that's a non-blocking API call so you have to proceed with the connection from within the callback (or use a promise interface and await that promise). In fact, pretty much all the programming with asynchronous calls here is wrong.