Sundar Sundar - 15 days ago 12
Javascript Question

Angular 2 promise is not waiting to resolved nested promise?

In my case I have to fetch the customers list on customerService and return back to the component. Please anyone can help me by rewriting the getCustomersList method.

import { Injectable } from '@angular/core';
import { SQLite } from 'ionic-native';

@Injectable()
export class CustomerService {
private sDBName:string;
private db;
private isDBExist:boolean = false;

constructor() {}

setDBName(sDBName:string) {
this.sDBName = sDBName;
}

connect():Promise<any> {
this.db = new SQLite();
return this.db.openDatabase({
name: this.sDBName,
location: 'default'
});
}
getCustomersList():Promise<any> {
return Promise.resolve(()=>{
return this.connect().then(()=>{
this.isDBExist = true;
let sql = 'SELECT * FROM customer ORDER BY customer_id DESC LIMIT 10';
return this.db.executeSql(sql, {}).then((result)=>{
let customers = [];
for(let i=0; i<result.rows.length; i++) {
customers.push(result.rows.item(i));
}
return customers;
},(err)=>{
this.debug('Unable to select customers', err);
return [];
});
},(err)=>{
this.debug('Unable to open database', err);
return [];
});
});
}
}

Answer

You use Promise in an absolutely unnatural manner. Promises are created to get rid of a so called callback hell. Promises are supposed to reduce asynchronous code complexity, but what you are doing is exactly the road to the callback hell.

I slightly rewrote your function in order to work according to the Promise standards. It might be a not working out of the box solution, but you did not provide us with any plunker, so this is just a concept:

getCustomersList(): Promise<any> {
  return this.connect()
         .catch(err => throw new Error('Unable to open database', err))
         .then(() => {
           this.isDBExist = true;
           return this.db.executeSql('SELECT * FROM customer ORDER BY customer_id DESC LIMIT 10', {})
         })
         .catch('cannot execute query')
         .then(result => result.rows.map(row => row.item(i)))
         .catch(err => {
           this.debug('Unable to select customers', err);
           return [];
         });
}

I really beleive the connecting to the database should not be done at this place but at some common database service which will be your database layer. Ideally when you call this function, the database should have already been connected / the error should be already thrown. So spend more time to think about the architecture.