I am trying to set an authentication and account creation page on my website (nothing too complicated, just getting started with express and SQLite). My issue is that my function to add users (or to connect) has callbacks on the different steps of interaction with the database, and i would like to wait for all of them to finish before ending the function so that I can transmit data back to the front through the express response. This data would include any error code from the database (user already exists to name one) and the actual user data when someone connects.
function addUser(username,password)
{
var db = new sqlite3.Database('./database/users.db',sqlite3.OPEN_READWRITE, (err) => {
if (err) {
console.error("open error code : "+err.errno+" ; msg : "+err.message);
}
});
var statement=db.prepare("INSERT into users(username,password) VALUES(?,?)")
statement.run(username,password,(err)=>{
if (err) {
console.error("run error code : "+err.errno+" ; msg : "+err.message);
}
});
statement.finalize((err)=>{
if(err)
{
console.error("finalize error code : "+err.errno+" ; msg : "+err.message);
}
})
db.close()
}
and ideally the server answer would look something like this
app.post('/addUser',jsonParser,(req,res)=>{
res.status(200).send(JSON.stringify({error : addUser(req.body.username,req.body.password)}))
});
Where addUser returns any err.errno generated within its steps (which it currently doesnt).
I have tried declaring a variable to store in the errors (and similarly store the user data for the connectAsUser(username,password) function) but the addUser(username,password)'s thread would finish before the callbacks on err. I also tried promises but i quickly turned into a mess of scopes.
EDIT : I managed to find a solution playing arround with promises and then().
The function code :
async function addUser(username,password)
{
var resp = {
openError : "",
runError : "",
finalizeError : ""
}
var data = {
db : null,
statement : null,
}
var promisedDB = new Promise((resolve,reject)=>{
var db = new sqlite3.Database('./database/users.db',sqlite3.OPEN_READWRITE, (err) => {
if (err) {
resp.openError=err.errno
reject()
}
else
{
data.db=db
resolve()
}
});
})
await promisedDB.then(_=>{
return new Promise((resolve,reject)=>{
var statement=data.db.prepare("INSERT into users(username,password) VALUES(?,?)")
statement.run(username,password,(err)=>{
if (err) {
resp.runError=err.errno
reject(err)
}
else
{
data.statement=statement
resolve()
}
})
})
}).then(_=>
{
return new Promise((resolve,reject)=>{
data.statement.finalize((err)=>{
if(err)
{
resp.finalizeError=err.errno
reject(err)
}
else
{
resolve()
}
})
})
}).then(_=>{
data.db.close()
}).catch(err=>{
console.log(err)
})
return resp
}
and the answer from the server is :
app.post('/addUser',jsonParser,(req,res)=>{
addUser(req.body.username,req.body.password).then((value)=>{
console.log(value)
res.status(200).send(JSON.stringify(value))
})
});
I've ran some tests and working with objects such as data{} in the addUser() function is mandatory to be able to edit the variable throughout the code (as in a passing a reference/adress in other languages).