Chained Database Promises Error


#1

Hi guys, I’m trying to fetch data from multiple tables.

The first table data contains a country_id column which I use to fetch the country name from the other table.

I have linked them together using a chain of promises but every time I run the app, I get the following error:

_{"_zone_symbol__currentTask":{“type”:“microTask”,“state”:“notScheduled”,“source”:“Promise.then”,“zone”:“angular”,“cancelFn”:“nullCount”:0}}

Below is my code snippet:

N.B: database is a SQLiteObject


  transactionPartners() {
    let partners = [];
    let rawPartners;
    let transactionPartners = [];
    let rows;
    return this.database.executeSql("SELECT * FROM corp_fin_tran_partners", {})
    .then((data1) => {
      rawPartners = data1;
      rows = data1.rows;
      for(let i = 0; i < rows.length; i++) {
        partners.push({
          id: rows.item(i).id, 
          company_id: rows.item(i).company_id, 
          name: rows.item(i).name, 
          email: rows.item(i).email, 
          tel: rows.item(i).tel, 
          comp_numb: rows.item(i).comp_numb, 
          tin: rows.item(i).tin, 
          address: rows.item(i).address, 
          country_id: rows.item(i).country_id, 
          state_id: rows.item(i).state_id, 
          document: rows.item(i).document
        }) 
      }
      return this.getCountry(partners);
    })
    .then((data2) => {
      for (let i = 0; i < rows.length; i++) {
        transactionPartners.push({
          id: rows.item(i).id, 
          company_id: rows.item(i).company_id, 
          name: rows.item(i).name, 
          email: rows.item(i).email, 
          tel: rows.item(i).tel, 
          comp_numb: rows.item(i).comp_numb, 
          tin: rows.item(i).tin, 
          address: rows.item(i).address, 
          country_id: rows.item(i).country_id, 
          state_id: rows.item(i).state_id, 
          document: rows.item(i).document,
          country: data2.rows.item(i).name
        })
      }
      return transactionPartners;
    })
    .catch((error) => {
      alert("transactionPartners(): " + JSON.stringify(error))
    })
  }
  getCountry(partners) {
    let countries = null;
    // let partners = this.mergePartners;

    partners.forEach( partner => {
      this.database.executeSql("SELECT name FROM countries WHERE id=(?)", [partner.country_id])
      .then((data) => {
        countries += data;
        alert(countries.rows.item(0).name);
      })
    })
    
    return countries;
  }

#2

The issue is in getCountry. You’re attempting to use an asynchronous value synchronously.

You can re-write it to something like this:

getCountry(partners) {
  let countries = [];

  return partners.reduce((promise, partner) => {
    return promise.then(_ => this.database.executeSql("SELECT name FROM countries WHERE id=(?)", [partner.country_id]))
    .then(result => {
      for(let i = 0; i < result.rows.length; i++) {
        countries.push(result.rows.item(i));
      }

      return countries;
    });
  }, Promise.resolve());
}

However I’ve changed the return result than what you’re expecting as it was easier to work with. So instead of a bunch of SQL responses, it’s just an array of the results.
So you can just do:

for(let country in data2) {
  transactionPartners.push({
    id: country.id
    ...

At least assuming that my code works.

Actually you should be able to remove that whole second block (that is, the (data2) block) as the code as-is should return what you want.