Home > Back-end >  Async call to API inside a loop in Angular
Async call to API inside a loop in Angular

Time:07-21

I have the following code:

  for (let member of this.pendingBilling) {
                      //start billing
                      let payLoad: any = {};
                      payLoad.credentials = this.credentials
                      payLoad.data = {
                        memberid: member.memberid,
                        payid: member.payid
                      }
                      var APIURL = globals.endpoint   "members/rb";
                      let options = { headers: new HttpHeaders().set('Content-Type', 'application/json') };
                      let body: any = payLoad;
                      this.httpClient.post(APIURL, JSON.stringify(body), options).subscribe(
                        result =>  {
                          let apiResponse: any = result;
                          if (apiResponse.success == 1) {
                            member.status = apiResponse.status
                            member.amount = apiResponse.amount
                          }
                          if (apiResponse.success == 0) {
                            member.status = apiResponse.status
                          }
                        },
                        error => {
                          member.status = 91
                        });
                        
                      //end billing
}

The problem Im facing is that they all run almost at the same time (simultaneously), while I would like to run a httpClient.post, wait for the response, and then run the next record.

I had this code inside a

processBilling(): void  {}

But this does not work even by deleting void

processBilling(): {}

The question is, is it possible for the loop to wait for the httpClient.post response and then move to the next record?

Thanks.

CodePudding user response:

you could use promises and chain them


let promiseChain = Promise.Resolve();
let apiUrl: string = `${globals.endpoint}members/rb`;

this.pendingBilling.foreach( ( billingData ) => {
    let payload : any = {
        credentials: this.credentials,
        data: {
            memberid: billingData.memberid,
            payid: billingData.payid
        }
    };
    let options = { headers: new HttpHeaders().set('Content-Type', 'application/json') };
    let body: any = payLoad;
    promiseChain = promiseChain.then( () => {
        return new Promise( (res, rej ) => { 
            this.httpClient.post(APIURL, JSON.stringify(body), options).subscribe( 
            result => {
                let apiResponse: any = result;
                if (apiResponse.success == 1) {
                    member.status = apiResponse.status
                    member.amount = apiResponse.amount
                }
                if (apiResponse.success == 0) {
                    member.status = apiResponse.status
                }
                res();
            },
            error => {
                member.status = 91
                rej();
            });
    });
});

CodePudding user response:

This may not the best solution, but it may work for you as it did for me in the past. I had a similar issue for sending emails through SendGrid, so I placed a delay of 500ms in between calls.

  delay(ms: number) {
    return new Promise(resolve => setTimeout(resolve, ms));
  }

And then

for (let member of this.pendingBilling) {
                      //start billing
                      ....
                      ....
                      ....
                      await this.delay(500) 
                      //end billing
}
  • Related