Optimal method for consecutively making N number of API calls in Angular 9 in a synchronous manner

Having a service method for API calls structured as follows:

getUsers(id){
  return this.http.get(`${env.apiURL}/id`)
}

Now, the requirement is to call this method for a list of users stored in an array:

userId=[1,2,3,4,5,6,7,8,9]

The goal is to retrieve and print results from all API calls by utilizing fork-join as shown below:

    let user1= this.http.get(baseurl+'users/userId[1]');
    let user2= this.http.get(baseurl+'users/userId[2]');//Similarly, there are 10 values

    forkJoin([user1, user2]).subscribe(results => {
      // results[0] corresponds to user1
      // results[1] corresponds to user2
    });

However, it was noticed that the API calls were executed in parallel rather than sequentially. The ideal scenario requires sequential (synchronous) API calls.

Is there a more efficient way to make these n (variable number of users) API calls sequentially? Note: There's also a need to introduce a delay of 500ms after each API call. Attempts with pipe(throttleTime(500)) following the forkJoin operation resulted in simultaneous execution of all API calls.

Answer №1

There are numerous approaches to completing this task. Here are a couple of them:


Method 1:

  users$ = from(this.userIds).pipe(
    concatMap(id => this.getUser(id)),
    take(this.userIds.length),
    toArray()
  );

Steps:

  • from - generates an observable that emits each array element separately
  • concatMap - maps the ID to an observable, subscribes to it, and emits the results. Only permits one subscription to getUser(id) at a time (synchronously)
  • take - indicates how many values our stream should take before completion
  • toArray - gathers emissions and emits them as an array upon completion

Method 2:

  users$ = from(this.userIds).pipe(
    concatMap(id => this.getUser(id)),
    scan((all: User[], user) => ([...all, user]), []),
  );

Steps:

  • from
  • concatMap
  • scan - aggregates emissions into a single array. Emits every time a new value is received.

Both methods should work effectively, but there is a distinction in behavior. Method #1 will emit only once, after all individual calls have finished. Method #2 will emit each time a new value is emitted. (If only one emission is desired, consider using reduce)

Take a look at this StackBlitz to observe the variations in output between the two methods.

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

Error in syntax: The tailwind import statement contains an unrecognized word and will not function correctly

After configuring Tailwind CSS with Next.js, I made changes to the tailwind.config.js file. However, after making these changes, the compilation process failed and resulted in the following error: Error - ./src/assets/styles/global.css:3:1 Syntax error: Un ...

The property slider in the d3 slider package is not found in the type 'types of d3'

I attempted to integrate a d3 slider into my d3 chart in Angular 2. I installed the d3slider package using the command: npm install --save @types/d3.slider. However, when trying to access the method "d3.slider()", an error occurred stating that "property ...

Modify certain parameters in the current route using Angular 6 router

Within my Angular 6 setup, the URLs are structured as follows: /{language}/{app_section}/{object_id}/{view}?queryparams... All sections of the application utilize a language selector component, which is included in the template of a parent route to ensur ...

There was an issue with fetching the JSON fields that were passed through a POST request to a

My venture into PHP and the Http Post method is a new experience for me. I've crafted a PHP script and have it running on the WAMP server. To test this script, I'm utilizing the Advanced Rest Client for Chrome. Here's a snippet of my PHP scr ...

Issue: The module 'MatChipList' (imported as 'i13$1') could not be located in '@angular/material/chips'

I am facing issues with upgrading my Angular project from version 5.x to 15.x due to the presence of alfresco-core dependencies. The errors I am encountering are causing obstacles in the process. Any assistance in resolving these problems would be greatly ...

Do not send the Angular 2 HTTP request with headers

As someone new to Angular2, I am working on building a data service and trying to include headers in each request. Here is my attempt at adding headers, but for some reason they are not being sent: import { Injectable } from '@angular/core'; im ...

The server will only load on Safari's localhost and not on Chrome's

My Node server is only working in Safari when using http://localhost:8000, but not in Chrome. Interestingly, using 127.0.0.1:8000 works on both browsers. I'm puzzled as to why localhost doesn't work in Chrome even though pinging localhost in my t ...

How can the return type of a function that uses implicit return type resolution in Typescript be displayed using "console.log"?

When examining a function, such as the one below, my curiosity drives me to discover its return type for educational purposes. function exampleFunction(x:number){ if(x < 10){ return x; } return null } ...

What is the best approach to incorporate a stopwatch?

I'm exploring ways to track the time it takes for a user to click a button. While I have a working solution, I'm curious if there's a more efficient method available. Below is my current implementation: export class MainComponent implements ...

Minimize the amount of information retrieved and shown based on the timestamp

I am currently working on storing and retrieving the date of a user request. For creating the timestamp, I use this code: const date = firebase.firestore.FieldValue.serverTimestamp(); This is how I fetch and display the data: <tr class="tr-content" ...

"Production mode is experiencing a shortage of PrimeNG(Angular) modules, while they are readily accessible in development

I've been diligently working on an Angular application that heavily relies on PrimeNG as the UI component framework. Initially, I had no issues deploying my app with Angular version 9 and PrimeNG version 8. However, a while ago, I decided to upgrade t ...

Utilizing Angular 2 Observable for showcasing a seamless flow of real-time information

Currently, my Angular 2 Web application is utilizing a Couchbase Server as its database. The data communication occurs through WebAPIs that interact with the CouchBase server. As of now, I am uncertain if this method is optimal, but I am constantly polling ...

Encountered a TypeError in Angular 2 related to zone.addTask operation

My code suddenly stopped working and I have no clue why. HTML: <a class="nav_link" [routerLink]="['RowList']"> <svg><use xlink:href="#icon-list"></use></svg> List </a> JS: @RouteConfig([ {path: ...

JavaScript and Angular are used to define class level variables

Hello, I'm currently diving into Angular and have encountered an issue with a class level variable called moratoriumID in my component. I have a method that makes a POST request and assigns the returned number to moratoriumID. Everything seems to work ...

Getting the received payload in Angular 4+

I am currently working on a front-end module in Angular and I need to send data from my app to another application where the user is already logged in. The data will be sent via POST request in JSON format. My question is, how can I access this payload i ...

Is it possible to externalize Angular 2 components?

Summary Can we implement a system similar to package.json for managing components in an Angular 2 application? Detailed Explanation Our application components are developed independently with their own services, constants, and internationalization strin ...

The extracted text from the window appears to be blank

When attempting to enclose a selected string between two characters, I am encountering an issue. For example, when selecting 'test' and clicking on the change button, the selected text should change to 'atestb'. However, although I am a ...

Receiving multiple Firebase notifications on the web when the same application is open in multiple tabs

I have implemented firebase push notifications in Angular 7 using @angular/fire. However, I am facing an issue where I receive the same notification multiple times when my application is open in multiple tabs. receiveMessage() { this.angularFireMess ...

I am puzzled as to why I keep receiving the error message "Cannot read property 'poPanel' of undefined"

CSS In my project, I am implementing a feature that displays an ordered list by looping through an array of objects and adding them on a button click. It works smoothly for adding items, but when I try to implement a remove function to delete each item, I ...

Commitments when using a function as an argument

While I have a good understanding of how promises function, I often struggle when it comes to passing a function as a parameter: var promise = new Promise(function(resolve, reject) { // Perform asynchronous task ec2.describeInstances(function(err, ...