Array is not updating properly due to delay in service calls in Angular

Viewed 419

I am calling same service multiple times in angular using while loop but due to delay in response of API my array is not updating properly. I want to call certain set of statement once the while loop & all the services response are completed.

 GetData(){
    var xyz = [];
    var pqr = [];
    this.startRow = 0;
    this.names=[];
    while(this.startRow <= this.num)
    {
      this.getEmpData();
      this.startRow = this.startRow + this.countRow;
      console.log("Pass1");
      console.log(this.names);
    }
    //due to delay in API response name array is coming as empty
    this.names.forEach(value => {
      xyz.push(value);
    });
   
  }
  getEmpData()
  {    
     this.empService.getEmpData(this.startRow,this.countRow,this.id,this.search).subscribe(data => {
        this.resp = data;
        this.names = this.names.concat(this.resp); 
        console.log(this.names);   
      })
   
  }

Response

Pass1
[]
Pass1
[]
(20) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]
(40) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]

I want the names to be updated in the while loop only or the statement after the while loop to be executed after once the name array is updated. Please help me out with the given issue.

2 Answers

You can achieve that like the following:

  • Use the expand operator, to repeat calling the getEmpData method while the condition is valid.
  • Use the reduce operator that "Applies an accumulator function over the source Observable, and returns the accumulated result when the source completes, given an optional seed value."
  • Return the observable from getEmpData method, instead of subscribing to it.
getData() {
  var xyz = [];
  var pqr = [];
  this.startRow = 0;
  this.names = [];

  this.getEmpData()
    .pipe(
      expand(() => {
        this.startRow = this.startRow + this.countRow;
        return this.startRow <= this.num ? this.getEmpData() : EMPTY;
      }),
      reduce(acc => acc)
    )
    .subscribe(() => {
      xyz.push(...this.names);
    });
}

getEmpData(): Observable<any> {
  return this.empService
    .getEmpData(this.startRow, this.countRow, this.id, this.search)
    .pipe(
      tap(data => {
        this.resp = data;
        this.names = this.names.concat(this.resp);
        console.log(this.names);
      })
    );
}

Try to use async-await in your getEmpData() method:

 async getEmpData()
  {    
      const data = await this.empService.getEmpData(this.startRow,this.countRow,this.id,this.search).toPromise();
      this.resp = data;
      this.names = this.names.concat(this.resp); 
      console.log(this.names);
  }
Related