Multiple HTTP Requests in Angular 20 with RxJS forkJoin

by Didin J. on Jun 15, 2025 Multiple HTTP Requests in Angular 20 with RxJS forkJoin

Learn how to use RxJS forkJoin in Angular 20 with standalone components to combine multiple HTTP requests and handle results efficiently in modern apps.

Making multiple HTTP requests and combining their responses is a common requirement in modern Angular applications. Whether you're fetching user profiles, loading dashboard data, or aggregating analytics from multiple endpoints, you need a way to manage concurrent HTTP calls cleanly and efficiently.

In this updated tutorial, you’ll learn how to use RxJS forkJoin with the latest Angular 20 using standalone components—no NgModules required. We'll walk through setting up your app, creating a service that fetches data from multiple APIs, and handling combined responses in a clean, reactive way using the HttpClient.


Setup (Angular 20, RxJS 7+)

We will create an Angular 20 application using Angular CLI from the terminal or command line. For that, we have to install a new @angular/cli or update an existing @angular/cli using this command from the terminal or command line.

sudo npm install -g @angular/cli

You can skip `sudo` if you are using the Command-Line or if your terminal allows it without `sudo`. To check the existing version of Angular CLI, type this command.

ng version

We are using Angular and RxJS versions. Next, we have to create a new Angular application using this command.

ng new angular-forkjoin

Answer the question the same as below.

? Would you like to add Angular routing? No
? Which stylesheet format would you like to use? SCSS   [ https://sass-lang.com/documentation/synta
x#scss

Next, go to the newly created Angular application folder, then run the Angular application for the first time.

cd ./angular-forkjoin
ng serve

Now, open the browser, then go to `http://localhost;4200/` and you will see the standard Angular page.

Multiple HTTP Requests in Angular 20 with RxJS forkJoin - run angular


Service: Combining Multiple HTTP Calls

The Angular `HttpClient` module should be registered in the Angular main module. Update src/app/app.config.ts:

import { ApplicationConfig, provideBrowserGlobalErrorListeners, provideZoneChangeDetection } from '@angular/core';
import { provideRouter } from '@angular/router';

import { routes } from './app.routes';
import { provideHttpClient } from '@angular/common/http';

export const appConfig: ApplicationConfig = {
  providers: [
    provideBrowserGlobalErrorListeners(),
    provideZoneChangeDetection({ eventCoalescing: true }),
    provideRouter(routes),
    provideHttpClient(),
  ]
};

The main feature that we mention in the title of this tutorial is using the RxJS forkJoin to call multiple RESTful API in one call. We do that in the Angular Service. For that, generate a new Angular service using Angular CLI.

ng g service rest-api.service

Next, open and edit `src/app/rest-api.service.ts` then add these imports of Observable, of, throwError (rxjs), HttpClient, HttpHeaders, HttpErrorResponse (@angular/common/http), forkJoin (rxjs).

import { Observable, of, throwError } from 'rxjs';
import { HttpClient, HttpHeaders, HttpErrorResponse } from '@angular/common/http';
import { forkJoin } from 'rxjs';

Add this line after the import lines as a constant variable of the RESTful API endpoint that we will use.

const apiUrl = 'http://localhost:1337/www.metaweather.com/api/location/';

As you see, we are using the `localhost:1337` in front of the Meta weather URL because the RESTful API, not CORS enabled. For that, we have to install the Corsproxy-HTTPS using this command.

sudo npm install -g corsproxy-https

Next, inject the `HttpClient` module into the constructor.

constructor(private http: HttpClient) { }

Next, create multiple RESTful API calls at once in a function using the above API URL with a different parameter value that describes the code of the city.

getData(): Observable<any> {
  const response1 = this.http.get(apiUrl + '44418/');
  const response2 = this.http.get(apiUrl + '2459115/');
  const response3 = this.http.get(apiUrl + '28743736/');
  const response4 = this.http.get(apiUrl + '1940345/');
  return forkJoin([response1, response2, response3, response4]);
}

As you see, the forkJoin combines the 4 API calls at the end of the function.

Note: Using forkJoin({ … }) returns a named object, preserving request order with keys instead of an array.


Component: Displaying Aggregated Results

Now, we have to display the 4 different API calls' responses to the Angular page using Angular Material. First, we have to add Angular Material using the Angular CLI.

ng add @angular/material

Answer all questions that appear during the installation as below.

? Choose a prebuilt theme name, or "custom" for a custom theme: Indigo/Pink        [ Preview: https
://material.angular.io?theme=indigo-pink ]
? Set up HammerJS for gesture recognition? Yes
? Set up browser animations for Angular Material? Yes

Next, open and edit `src/app/app.ts`, then add this import.

import { Component } from '@angular/core';
import { RestApiService } from './rest-api.service';
import { CommonModule } from '@angular/common';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { MatCardModule } from '@angular/material/card';

Add these to the component imports.

@Component({
  selector: 'app-root',
  imports: [
    CommonModule,
    MatProgressSpinnerModule,
    MatCardModule
  ],
  templateUrl: './app.html',
  styleUrl: './app.scss'
})

Add these lines of variables after the title variable.

data1: any = {};
data2: any = {};
data3: any = {};
data4: any = {};
isLoadingResults = true;
error?: string;

Add the constructor that injects the REST API service and call the get data function.

constructor(private api: RestApiService) {
  this.getData();
}

Add a function to get data from the REST API service.

  getData() {
    this.api.getData()
      .subscribe({
        next: (res) => {
          console.log(res);
          this.data1 = res[0];
          this.data2 = res[1];
          this.data3 = res[2];
          this.data4 = res[3];
          this.isLoadingResults = false;
        },
        error: (err) => (this.error = 'Failed to load data')
      });
  }

Next, open and edit `src/app/app.html`, then replace all existing HTML tags with these tags.

<div class="example-container mat-elevation-z8">
  <div class="example-loading-shade"
       *ngIf="isLoadingResults">
    <mat-spinner *ngIf="isLoadingResults"></mat-spinner>
  </div>
  <mat-card class="example-card">
    <mat-card-header>
      <mat-card-title><h2>{{data1.title}}</h2></mat-card-title>
      <mat-card-subtitle>Sunrise at {{data1.sun_rise | date: 'HH:mm:ss'}}, Sunset at {{data1.sun_set | date: 'HH:mm:ss'}}</mat-card-subtitle>
    </mat-card-header>
    <mat-card-content>
      <ul>
        <li *ngFor="let source of data1.sources"><a href="{{source.url}}" target="_blank">{{source.title}}</a></li>
      </ul>
    </mat-card-content>
  </mat-card>
  <mat-card class="example-card">
    <mat-card-header>
      <mat-card-title><h2>{{data2.title}}</h2></mat-card-title>
      <mat-card-subtitle>Sunrise at {{data2.sun_rise | date: 'HH:mm:ss'}}, Sunset at {{data2.sun_set | date: 'HH:mm:ss'}}</mat-card-subtitle>
    </mat-card-header>
    <mat-card-content>
      <ul>
        <li *ngFor="let source of data2.sources"><a href="{{source.url}}" target="_blank">{{source.title}}</a></li>
      </ul>
    </mat-card-content>
  </mat-card>
  <mat-card class="example-card">
    <mat-card-header>
      <mat-card-title><h2>{{data3.title}}</h2></mat-card-title>
      <mat-card-subtitle>Sunrise at {{data3.sun_rise | date: 'HH:mm:ss'}}, Sunset at {{data3.sun_set | date: 'HH:mm:ss'}}</mat-card-subtitle>
    </mat-card-header>
    <mat-card-content>
      <ul>
        <li *ngFor="let source of data3.sources"><a href="{{source.url}}" target="_blank">{{source.title}}</a></li>
      </ul>
    </mat-card-content>
  </mat-card>
  <mat-card class="example-card">
      <mat-card-header>
        <mat-card-title><h2>{{data4.title}}</h2></mat-card-title>
        <mat-card-subtitle>Sunrise at {{data4.sun_rise | date: 'HH:mm:ss'}}, Sunset at {{data4.sun_set | date: 'HH:mm:ss'}}</mat-card-subtitle>
      </mat-card-header>
      <mat-card-content>
        <ul>
          <li *ngFor="let source of data4.sources"><a href="{{source.url}}" target="_blank">{{source.title}}</a></li>
        </ul>
      </mat-card-content>
    </mat-card>
</div>

Finally, open and edit `src/app/app.scss`, then add these lines of SCSS code to make an adjustment for the styles.

.example-container {
  position: relative;
  padding: 5px;
  background-color: aqua;
}

.example-loading-shade {
  position: absolute;
  top: 0;
  left: 0;
  bottom: 56px;
  right: 0;
  background: rgba(0, 0, 0, 0.15);
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
}

.example-card {
  margin: 5px;
  padding-bottom: 40px;
}


Handling Conditional or Nested Requests

If you need to make additional calls based on previous results, combine forkJoin with mergeMap or switchMap. Example:

import { forkJoin, mergeMap, Observable } from 'rxjs';

  getDataWithDetails(): Observable<any> {
    return this.http
      .get<{ id: string }[]>(`${apiUrl}list`)
      .pipe(
        mergeMap((items) => {
          const detailCalls = items.map(item =>
            this.http.get(`${apiUrl}details/${item.id}`)
          );
          return forkJoin(detailCalls);
        })
      );
  }


Key RxJS Tips in Angular 20


Run and Test the Complete Angular RxJS Example

As you see in the previous steps, we have already installed the Corsproxy-HTTPS Node module. So, open the new Terminal/Command Line tab, then run the Corsproxy before running the Angular Application.

corsproxy

Back to the current Terminal tab, type this command to run the Angular application.

ng serve

In the browser, go to `http://localhost:4200/`, then you will see a single page like below.

Angular 8 RxJS Multiple HTTP Request using the forkJoin Example - Weather List


Conclusion

Angular 20 and RxJS 7+ provide a powerful and concise way to handle multiple HTTP requests using forkJoin. With standalone components and modern reactive patterns, your code is cleaner, modular, and easier to maintain.

Key benefits of using forkJoin in Angular:

  • Combine parallel HTTP requests and wait for all to complete

  • Use named keys for clear and predictable responses

  • Simplify UI logic by handling all results in one place

By applying these modern Angular features, you’ll write less boilerplate and build more scalable frontend code. Don’t forget to explore other RxJS operators like combineLatest, switchMap, or mergeMap for handling more dynamic or conditional workflows.

That's the Angular RxJS Multiple HTTP Request using the forkJoin Example. You can find the full source code on our GitHub.

If you don’t want to waste your time designing your front-end or your budget to spend by hiring a web designer, then Angular Templates is the best place to go. So, speed up your front-end web development with premium Angular templates. Choose your template for your front-end project here.

That's just the basics. If you need more deep learning about MEAN Stack, Angular, and Node.js, you can take the following cheap course:

Thanks!