Frank
Frank

Reputation: 2431

Angular How to make subscribe wait for a call to finish

INSERT NOTE: This question is not the same as most of the other questions relating to stuff like "How do I return the response from an asynchronous call?" because of the fact that it uses SUBSCRIBE. As far as I understand it, subscribe tells it to do something whenever this thing is changed, therefore you cannot put code inside the subscribe, because it will only ever run when it gets changed (which will always be too late). Please only answer if you have knowledge of Angular, Subscribe and the HttpClient. Now my original question:

I have a problem where I loop through an array and do a get call for each item in the array. My problem is that all these get requests happen asynchronously, which means they all try to get while the previous gets are still receiving their responses. This causes an error. Here is a rough example:

 this.MyArray = [1, 2, 3, 4, 5];   

 this.MyArray.forEach(element => {
      this.httpClient.get('http...')
      .subscribe(
        (response: any) => {
      })
 )}

How do I let the forEach loop wait for the call response before moving on to the next item in the loop? I tried looking at responses but I just can't understand it :(

Upvotes: 1

Views: 1856

Answers (2)

Tomasz Kula
Tomasz Kula

Reputation: 16837

You can map your array into observable streams. Then you can use concat operator to execute the observables in a row.

import {
  concat
} from 'rxjs/observable/concat';


this.MyArray = [1, 2, 3, 4, 5];

const observables: Observable<any>[] = this.myArray.map(() => this.httpClient.get('http...'));

concat(...observables).subscribe(resp => {
  // handle responses, they will execute one after another,
  //  each waiting for the previous one to finish
})

Upvotes: 1

Parshwa Shah
Parshwa Shah

Reputation: 341

Try this

this.totalCount = this.MyArray.length;
this.i=1;

getData(){

 let ob = this.MyArray[this.i-1];

 this.httpClient.get('http...')
      .subscribe(
        (response: any) => {
            this.i++;
             if(this.i <= this.totalCount){
               getData()
             }
      })
}

Upvotes: 1

Related Questions