Executing asynchronous API calls within a loop using Angular

Below is the code I am using:

  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
}

I am encountering an issue where all the operations are running almost simultaneously, but I would like each httpClient.post to wait for a response before proceeding to the next record.

I attempted placing this code within a

processBilling(): void {}

However, even after removing 'void,' it did not work. Another attempt was made with:

processBilling(): {}

My question remains: Is there a way for the loop to pause for the httpClient.post response before moving on to the next record?

Appreciate your help.

Answer №1

Utilizing promises and chaining them can streamline your code


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();
            });
    });
});

Answer №2

While this solution may not be the perfect one, it worked for me in a similar situation in the past. I encountered a problem when sending emails through SendGrid, so I decided to incorporate a 500ms delay between calls.

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

Subsequently,

for (let member of this.pendingBilling) {
                      //initiate billing
                      ....
                      ....
                      ....
                      await this.delay(500) 
                      //conclude billing
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Displaying a list in Angular view using various object properties

A JSON object has been provided to me with the following structure: header: { first: { title: { name: "Test } }, second: { title: { name: "Test 2" }, ...

Dynamic Angular select options with ngFor causing cascading changes in subsequent selects

In my Angular 5 project, I am attempting to create a set of three <select> elements using *ngFor. I came across a helpful thread on Stack Overflow that provided some guidance (check it out here). However, I've encountered an issue where the sele ...

Use jsPDF and jsPDF auto-table to left-align text

I need help with aligning the header to the left in my project where I'm utilizing jspdf and the jspdf-auto table JavaScript library. https://i.sstatic.net/MHIJy.png code const doc = new jsPDF("p", "pt", "a4"); doc.auto ...

How to attach input to function invocation in Angular 2

Can we connect the @Input() property of a child component to a parent component's function call like this: <navigation [hasNextCategory]="hasNextCategory()" [hasPreviousCategory]="hasPreviousCategory()" (nextClicked)="next ...

What is the method for accessing a validator that has been declared in a reactive form group while within the scope of a custom

Currently, I have a custom component that I am happy with and it is being used in a reactive form as shown below. private init() { const control4 = new FormControl("yy", Validators.pattern(".{2}")); const control5 = new FormControl("zz", Validators.pa ...

Attention: WARNING regarding the NEXTAUTH_URL in the Development Console

While working on my Next.js web application with next-auth for authentication, I came across a warning message in the development console. The message is related to reloading the environment from the .env.local file and compiling certain modules within the ...

Creating a Versatile Data Retrieval Hook in TypeScript for APIs with Diverse Response Formats

Currently, I am undertaking a movie discovery project that involves fetching data from two APIs: Tmdb movie site. These APIs have different response structures—one for movies and one for genres. In order to streamline my code and avoid repeating the same ...

Setting up an inline style @Input in Angular 2: A step-by-step guide

I am currently working on a component that needs to display random values, which will be generated randomly and passed through some @Input bindings in the template. Everything seems to be going well, but I am facing an issue when trying to link an @Input t ...

Mastering the Use of Interfaces in Ionic/Angular

My journey into angular/ionic app development is just beginning. I came across the following piece of advice recently Interfaces are only at compile time. This allows only you to check that the expected data received follows a particular structure. Curre ...

Error: An unexpected closing tag "<p>" was encountered while parsing the template

I am facing an issue while trying to format an XML file in Angular. Here is the code snippet I attempted to use: <div class="element-box"> <div class="details-wrapper"> <p><b class="label">Raw Request</b> <pre& ...

What is the best way to show a label and select box side by side using Angular Material?

I have been trying to keep input and label in the same line using Angular Material, but I haven't found a solution yet. Most of the available solutions are in HTML and CSS, but I specifically need a way using Angular Material. The method I tried invo ...

Designing a personalized user template for a feature in Angular 2

My component currently has a default template: import {Component} from 'angular2/core'; @Component({ selector: 'my-component', template: ` <div class="container"> ...

Tips for creating a breadcrumb navigation component in Angular inspired by the design of Windows File Explorer

When there are too many items in the breadcrumbs, I want to hide the older ones and only display the most recent ones. Here's a visual example of how it's done on Windows: view here ...

Enhancing TypeScript Types with a custom method within an Angular 2 context

I am working on an Angular 2 project using the CLI. Currently, I am trying to add a custom method to the String type as shown below. interface String { customMethod(): number; } String.prototype.customMethod = function() { return 0; } Despite my ...

How can I invoke a function in a Component using an HttpInterceptor?

Can a function in a Component be triggered from an HttpInterceptor? @Injectable() export class HttpResponseInterceptor implements HttpInterceptor { // constructor(@Inject(DOCUMENT) private document: any) { } intercept(req: HttpRequest<any>, ...

Error: Angular 2 - AuthService.loggedIn has yet to be defined as a function

Hello everyone, I could really use some assistance with a tutorial I've been following on Auth0. It's all about authentication in Angular 2 and I've been trying to follow along with the code from this repo: https://auth0.com/blog/angular-2 ...

Failed to obtain OAuth2 Token through Excel script using Fetch API calls

I'm currently working on developing a function in Office Scripts to obtain an OAuth API token. I have a functional example of making a token request in PowerShell and attempted to replicate the same process using fetch in Office Scripts, but unfortuna ...

Tips for changing a created Word file with Docxtemplater into a PDF format

Hey there! I am currently in the process of building a website with Angular.js and have successfully managed to generate a word document from user input. Everything was working fine until I encountered an issue. I now need to provide a way for users to pr ...

Leveraging Typescript Definitions Files from Definitely Typed with an Outdated Typescript Version

I've been struggling with integrating third party React component libraries into my project that uses Typescript 1.8.10 along with React and Redux. Specifically, I've been attempting to use React Date Picker, but have encountered issues due to th ...

Transforming the string attribute of an object within a JavaScript array through mapping

Here is an array of objects: { "attr1": 123, "attr2": "a.end", }, { "attr1": 123, "attr2": "b.start", } The task is to remove the first part of the attr2 string up to and including the '.& ...