2

I use Ionic 2 with Angular 2 in my project. In the root component you can click a "Add" button to add a new Report via a complex form and a lot of preprovided data (there are some selects that are feeded with data fetched from sqlite database) Now in my "CreateReportComponent" i have the following constructor to load the data and assign it to local array variable:

selectEmployeeOptions: Employee[];

constructor(private dbService: DatabaseService) {
  dbService.getAllEmployees().then(employees => {
      this.selectEmployeeOptions = employees;
  });

  // load more data like tasks etc.
});

But when I want to modify this data in my component, the array is empty. I tried to do it in ngOnInit() but this seems to be to early as well.

I want to to something like this, before the component gets displayed:

  dbService.getAllEmployees().then(employees => {
      this.selectEmployeeOptions = employees;

      // modify data
      this.selectEmployeeTitleOptions = employees.map((item) => {
         return item.title;
      });
      console.log(JSON.stringify(this.selectEmployeeTitleOptions)) // --> empty
  });

But selectEmployeeTitleOptions is empty...

The function in the databaseService looks like this:

getAllEmployees(): Promise<Emplyoee[]> {
  let query = "SELECT * FROM employees";
  let employeeList = [];
  this.database.executeSql(query, []).then((data) => {
     if(data.rows.length > 0) {
       let e = new Employee();
       e.id = data.rows.item(i).id;
       e.firstname = data.rows.item(i).firstname;
       e.lastname = data.rows.item(i).lastname;
       employeeList.push(e);
     }
  }, (error) => {
     // handle error
  });
  return Promise.resolve(employeeList);
}

I read that there is the Resolve pattern (https://blog.thoughtram.io/angular/2016/10/10/resolving-route-data-in-angular-2.html) But I need to make multiple calls and not only for contacts as in the example.

So the question: How to wait for multiple calls to database?

GrübelDübel
  • 165
  • 10

3 Answers3

1

i think something go wrong here

getAllEmployees(): Promise<Emplyoee[]> {
  let query = "SELECT * FROM employees";
  let employeeList = [];
  this.database.executeSql(query, []).then((data) => {
     if(data.rows.length > 0) {
       let e = new Employee();
       e.id = data.rows.item(i).id;
       e.firstname = data.rows.item(i).firstname;
       e.lastname = data.rows.item(i).lastname;
       employeeList.push(e);
     }
  }, (error) => {
     // handle error
  });
  return Promise.resolve(employeeList);
}

first return Promise.resolve(employeeList); will return empty array, because it is async process. you need loop through data.rows, then format return data like this.

getAllEmployees(): Promise<Employee[]> {
  let query = "SELECT * FROM employees";
  return this.database.executeSql(query, []).then((data) => {
    let arr = [];
    for(let i = ; i < data.rows.length; ++i) {
      let emp = data.rows.item(i);
      let e = new Employee();
      e.id = emp.id;
      e.firstname = emp.firstname;
      e.lastname = emp.lastname;
      arr.push(e);
    }
    return arr;
  });
}

note that .then() return a promise object.

Tiep Phan
  • 12,386
  • 3
  • 38
  • 41
0

What you are looking for is forkJoin method that returns Observable that you should switch to instead of using Promises, for reference about why you should do this check here.

Short information about fork join from its GitHub page:

Runs all observable sequences in parallel and collect their last elements.

This way you can safely make parallel requests to your API.

For more information regarding forkJoin go here.

Additionally you should call services using ngOnInit as you mentioned before. For more information about Angular 2 lifecycle hooks see the docs.

Community
  • 1
  • 1
Gorsky
  • 13
  • 4
0

You can use Promise.all https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise/all

You push all promises to an array, and then go

    let foo : [Promise<Emplyoee[]>,Promise<void>] = [getAllEmployees(), method2()];
    Promise.all(foo).then((results:any[]) => {
       let employeearray: any = results[0];
       /* and on an on */
     });
n00b
  • 1,832
  • 14
  • 25