0

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).

  • Just [promisify](https://stackoverflow.com/questions/22519784/how-do-i-convert-an-existing-callback-api-to-promises) your callback-based functions. Or try to find if your sqlite3 lib has promises api. – Sergey Sosunov Feb 26 '23 at 17:00

1 Answers1

-1

Maybe try

async function addUser() { return data}
var data = await addUser();
//blocking if resolve and next ....
app.post({send:data})

or

async function addUser() { return data}
addUser().then((data)=>{app.post({send:data})});
   //non-blocking and next ....

or

var resp = {}
var response= new Promise((resolve)=>{resp.resolve = resolve})

async function addUser() { 
example.run(a)=>{
resp.resolve(a);
}}
response.then((data)=>{app.post({send:data})});

or

async function* reader() {
  while (true) {
    const value = yield;
    console.log(value, '-----generator');
  }
}

const read = reader();
var i =0

read.next(0) //first value not return

async function create(val) {

await read.next(val); 



}

function addUser() {

example.run((a)=>{
create(a)
})

or

async function addUser() { 
example.run(a)=>{
readData(a)
}}

async function readData(val) {
app.post()
}

or RxJS libary test

the first locks the code underneath inside the function it resides in, the second doesn't wait inside then

------ edit

Everything that was needed can be found here https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/resolve. This is in the overview tab. These are the basics of js.

async function addUser() {
  var func = ()=>{return Promise.resolve('data from callback');}
  return func()
  }
addUser().then((val)=>{console.log(val)})

Async post function in NodeJS

Pawells
  • 27
  • 8
  • My issue is that I have no way of recovering the data I want since it's processed in the callback of statement.run(username,password,(err)=>{ //here// }. Waiting for addUser() to finish doesn't help in waiting for the callback on err. – jayqui-grisli Feb 26 '23 at 20:48
  • Now it should work without any problem – Pawells Feb 26 '23 at 22:23
  • it's not quite what I'm looking for, but your third option coupled with what was pointed ou to me here https://stackoverflow.com/questions/22519784/how-do-i-convert-an-existing-callback-api-to-promises gave me hints on what to look for. I'll edit with a working solution. – jayqui-grisli Feb 27 '23 at 15:41
  • after all the answer this working example is exactly like this 3 option, you resolved the promises in example.run and picked up after that, not only that, all 5 would work the same, see example 2, You've combined 2 and 3 more, 1 does the same – Pawells Feb 27 '23 at 16:04