Search code examples
angulartypescriptangular-httpclientangular4-httpclient

How to wait and get response for each HttpClient service call from a loop in Angular 4


I have a situation where I need to run a loop and fetch respective items' description. Then along with the item Ids and other information I have to include the fetched description in a datatable.

addDescription(){
this.arrayOfItems.forEach(element => {

   // CALL a function which will make a service call
   this.fetchDescription(element);

   //CODE TO DECLARE AN INTERFACE TO ASSIGN RESPECTIVE VALUES. eg.

   // ITEM_ID : element.id,
   // ITEM_DEF : this.fetchedDescription.join("\n")
}

Function body:

fetchDescription(elementToFetchDesc){

 //Declaring HTTPPARAMS in PassingParams variable

 this.componentService.getDesc(PassingParams)
         .subscribe((response: HttpResponse<any>) => {
                if(response.status ==200){
                    this.fetchedDescription = reponse.body.output.slice(6,-1);
                }
                //Code if response status is NOT 200
}

In componentService Service:

construcutor(private httpConn: HttpClient){}

getDesc(Params){
    // Declare URL
    return this.httpConn.get(URL, {params: Params, observe: 'response'});
}

The problem:

As it's running in a loop and the subscription is an async call, so, after running the loop in forEach it's coming out. As a result the description is not getting assigned to the variable (ITEM_DEF) in the interface.

To solve this issue I implemented a little change to use promise. In service I added:

 import 'rxjs/add/operator/toPromise';

And updated the service method as:

 return this.httpConn.get(URL, {params: Params, observe: 'response'})
                     .toPromise();    // converted observable into promise

Also changed in component: Inside fetchDescription function:

replaced .subscribe as .then

But the issue still persists. Please let me know where I'm doing wrong to implement this logic.


Solution

  • the solution is to convert observable to promise but not using then!

    Example:

    This is your service function that sends the request:

    myRequest(num) {
       return this.http.get('http://someUrl.com/' + num).toPromise(); 
    }
    

    This is the function to send all requests in a component class:

     async sendAll() {
        let response = [];
        for(let i = 0; i < 5; i++) {
            response[i] = await this.myService.myRequest();
        }
      // Got all the results!
     }