Search code examples
typescriptasync-awaitfirebird

Problem with async/await service response with callback


I am using the node-firebird JavaScript module to query a Firebird database.

The module responds with a callback, and I can't get the async / await working for me to wait for the response from that module.

A "padron.controller" controller makes a call to a "padron.service" service to make a query

try {
  let res = await this.padronService.getFamilia(body);
  console.log('padron.controller - Response from padron.service', res);
  return res;
} catch {
  throw new Error('Erro na DB');
}

"padron.service" call to "firebird.service" which centralizes all the query to the DB.

try {
  let res = await this.firebirdService.getQuery(query, params);
  console.log('padron.service - Response from FirebirdService ================', res);
  return res;
} catch {
  throw new Error('Erro na DB');
}

The "firebird.service" uses a "node-firebird" library and and returns with a callback.

fb.attach(this.options, (err, db) => {

        if (err) throw new Error('Erro na conexión á DB');

        db.query(query, params, (err, res) => {

            if (err) throw new Error('Erro na consulta ó Padrón');;

            console.log('firebird.service - Response DB ================', res);

            db.detach();

            return res

        });

    });

My problem is the order of the answers

padron.service - Response desde FirebirdService ================ undefined
padron.controller - Response desde padron.service undefined
firebird.service - Response DB ================ {
    USU_USUARIO: 'SUPER',
    USU_CLAVES: '',
    USU_CARGO: 'ADMINISTRADOR',
    USU_TER: null,

when the order should be

firebird.service - Respuesta DB ================ { 
    USU_USUARIO: 'SUPER',
    USU_CLAVES: '',
padron.service - Respuesta desde FirebirdService ================ undefined
padron.controller - Respuesta desde padron.service undefined

The await does not wait for the callback from the DB

And I don't know how to fix it.


Solution

  • Wrap the code that you mentioned in padron.service with a promise like below. Now the value that is returned from the db is returned through passing it in resolve callback, and if there is some error, pass it in reject callback.

    Note that in case of error, pass it to reject callback in asynchronous tasks as it will not give unexpected output in comparison to throwing the error

    return new Promise((resolve, reject) => {
        fb.attach(this.options, (err, db) => {
    
            if (err) {
                // throw new Error('Erro na conexión á DB');
                reject('Erro na consulta ó Padrón');
            }
    
            db.query(query, params, (err, res) => {
    
                if (err) {
                    // throw new Error('Erro na consulta ó Padrón');
                    reject('Erro na consulta ó Padrón');
                }
                console.log('firebird.service - Response DB ================', res);
    
                db.detach();
                // return res
                resolve(res);
            });
        });
    });