Execute service operations simultaneously and set the results in the sequence they are received

I am faced with a challenge involving multiple service methods that fetch data from various servers. The responses from these APIs come in at different times, and I need to store the responses in variables as soon as they are received.

Here are my service methods:-

GetDataServer1(req) {   
    return this._http.post("server1", req)
      .pipe(
        tap((res) => console.log(res)),
        map((res) => res), catchError(this.handleError.bind(this)));
  }

GetDataServer2(req) {   
    return this._http.post("server2", req)
      .pipe(
        tap((res) => console.log(res)),
        map((res) => res), catchError(this.handleError.bind(this)));
  }

GetDataServer3(req) {   
    return this._http.post("server3", req)
      .pipe(
        tap((res) => console.log(res)),
        map((res) => res), catchError(this.handleError.bind(this)));
  }

Currently, the data is logged in the console based on the order of received responses. Even though I've tried using forkJoin and zip from the component to gather data, I only receive the data when all service methods have been executed. What I actually need is to get a response as soon as any API returns data.

Below is my component method for reference:-

getData(data){
  req1 = this.service.GetDataServer1(data);
  req2 = this.service.GetDataServer1(data);
  req3 = this.service.GetDataServer1(data);
  forkJoin([req1,req2,req2])
      .subscribe(([res1,res2,res3]) => {
            console.log(res1);
            console.log(res2);
            console.log(res3);
})
}

Can anyone advise me on how to achieve fetching data in line with my requirements?

Thank you for your assistance.

Answer №1

To handle data, you can utilize a subject and trigger the next function when new data is received. Here's an example:

  myData$ = new BehaviorSubject([]);
  apiUri = "";
  constructor(private _http: HttpClient) {}
  updateData(res) {
    this.myData$.next([...this.myData$.value, res]);
  }
  handleError = err => {
    console.log(err);
  };
  GetDataServer1(req) {
      // Code for server1
  }

  GetDataServer2(req) {
      // Code for server2
  }

  GetDataServer3(req) {
      // Code for server3
  }

  getData(data) {
    const req1 = this.GetDataServer1(data);
    const req2 = this.GetDataServer1(data);
    const req3 = this.GetDataServer1(data);
    
    forkJoin([req1, req2, req2]).subscribe();
    this.myData$.subscribe({
      next: res => console.log(res)
    });
  }

Take a look at this live demo

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

The TypeScript function was anticipating one argument, however it received two instead

Can you help me fix the issue with my createUser() function? Why am I unable to pass parameters in Smoke.ts? Login.ts : interface User { url: string, email: string, } class Test{ async createUser(user: User) { await Page.setUrl(user.url); aw ...

Angular2/TypeScript Coding Guidelines

I am curious about the common practices and consensus among the Angular2 community when it comes to writing reusable code in TypeScript. I have gathered some information and questions related to Angular2 that I would like to discuss. Organizing Module/A ...

Is there a way to specifically choose the initial element using Angular? "Backend powered by Django"

Hi there! I've set up Django on the back-end to send data to Angular, and I'm trying to display only the first comment from a list in my HTML page. However, when using limitTo, I encountered this error: Failed to compile. src/app/app.component. ...

What could be causing the sorting function to malfunction on certain columns?

My table's column sorting feature works well with first name and last name, but it seems to have issues with dl and dl score columns. I need assistance in fixing this problem. To access the code, click here: https://stackblitz.com/edit/angular-ivy-87 ...

Tips for generating a list in Angular2 based on previous selections

import { Component } from '@angular/core'; export class Superhero { name: string; } const SUPERHEROES: Superhero[] = [ { name: 'GK-1' }, { name: 'GK-2' }, { name: 'GK-3' }, { name: 'GK-4&ap ...

Addressing the Angular Auth0 Error: State Validation Problem

Currently, I am in the process of integrating Auth0 into my Angular application (I am utilizing the .NET Core Angular project template within VS2022). .NET 6 Angular: 13.0.2 @auth0/auth0-angular: 1.8.0 To start off, I referred to https://auth0.com/docs/q ...

Angular Material transition animation in fading style

After implementing the routing animation for my Angular 6 + Material app following this answer, I decided to switch to a different animation effect: const fade = [ // route 'enter' transition transition(':enter', [ // css styles ...

How to make Angular resolver and component share an injected service?

In my products list component, I have a table displaying various products. Since there is a considerable amount of data, I implemented a resolver to prevent the user from being directed to the page until all the data is loaded. The resolver currently utili ...

Prevent overlapping of range sliders in HTML and CSS

I have designed a range slider with two buttons, but they are overlapping each other. I want to ensure that they do not cross over one another - where the value of the first button should be equal to the minimum value of the second button, and the maximum ...

What is the best way to restrict the suggested values in a property depending on the value of another property?

I'm working on creating a third interface that depends on the value of properties from two other interfaces, while also introducing a unique third property. I've chosen not to extend the third property from the first two interfaces as it may not ...

The JsonFormatter is throwing an error because it is trying to access the property 'on' of an undefined variable

I have encountered an error while attempting to generate an HTML report using cucumber-html-reporter The error message is: Unhandled rejection TypeError: Cannot read property 'on' of undefined at new JsonFormatter (C:\path-to-project\ ...

Iterate through elements in Angular using *ngFor with a TrackBy function across two levels of nested

I am currently dealing with 2 nested loops in my code, set up like this: <div *ngFor="let page of pages; trackBy: trackByPageId" class="page"> <app-item-component *ngFor="let item of page; trackBy: trackByItemID" ...

Issue with NestJS verification of AWS Cognito JWT: "Error: applicationRef.isHeadersSent function not recognized"

I have integrated AWS Cognito as the authentication service for my NestJS application. However, when accessing the endpoint without a JWT (unauthenticated), the server crashes and displays the error TypeError: applicationRef.isHeadersSent is not a function ...

Tips for sending FormData and request body with angular's httpclient

I need help updating my Angular application package from @angular/http to @angular/common/http. During the process, my code is breaking for a specific reason. Previously, I was able to send both form data and request body in the following manner: this.ht ...

Shifting the Ion Menu side dynamically based on screen size: A step-by-step guide

Working with Ionic 4, I encountered the need to dynamically change the side property of ion-menu. On larger screens, ion-menu is always visible or static, whereas on smaller screens, it remains hidden until the user clicks on the ion-menu-button. My goal i ...

Configuration file for proxying both HTTP requests and WebSockets to the same endpoint

In my development environment, I have successfully set up a proxy for http requests to a django server on my backend/laptop using a proxy.conf.json configuration file: { "/graphql": { "target": "https://localhost:443/gr ...

Guide for transferring the body of a table to a different component without disrupting the design aesthetics

In an attempt to reorganize my large table component, I decided to separate its body section into a new component. However, every time I try to do this, the styling of the table breaks (likely due to the new HTML structure in the code). I'm currently ...

The issue of TypeScript failing to return HTML Template Element from Constructor typing is causing complications

There is a restriction on using new to create an instance of Template, which extends an HTMLTemplateElement. To work around this limitation, I fetch and return an HTMLTemplateElement by using document.getElementById(id) within the constructor of the Templ ...

Fetching data in VueJs before redirecting to a new page

Within the mounted function, I am creating an action that fetches data from a Rest API and populates my table in a Vue.js component mounted() { UserService.getProjects().then( (response) => { this.isProject = true; this.project ...

### Setting Default String Values for Columns in TypeORM MigrationsDo you want to know how to

I'm working on setting the default value of a column to 'Canada/Eastern' and making it not nullable. This is the current setup for the column: queryRunner.addColumn('users', new TableColumn({ name: 'timezone_name', ...