How To Use ForkJoin — Angular Example

How To Use ForkJoin — Angular Example

forkJoin is a useful operator in Angular’s RxJS library for combining the results of multiple observables into a single observable. It waits for all the source observables to complete and then emits an array of the last values emitted by each source observable.

Here’s a real-world example of how forkJoin can be used in an Angular app:

Let’s say we have an application that displays posts information, including the comments for a given post. We want to fetch this information from separate API endpoints and display it on a single page.

First, let’s define the interfaces for our post and comment data:

export interface Post {
  id: number;
  title: string;
  body: string;
}

export interface Comment {
  id: number;
  postId: number;
  name: string;
  email: string;
  body: string;
}

Next, we can create a service called PostService that handles the API calls and returns observables for the post and comment data:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';

@Injectable()
export class PostService {
  private apiUrl = 'https://jsonplaceholder.typicode.com';

  constructor(private http: HttpClient) {}

  getPost(postId: number): Observable<Post> {
    const url = `${this.apiUrl}/posts/${postId}`;
    return this.http.get<Post>(url);
  }

  getComments(postId: number): Observable<Comment[]> {
    const url = `${this.apiUrl}/comments?postId=${postId}`;
    return this.http.get<Comment[]>(url);
  }
}

Now, in a component, let’s say PostDetailsComponent, we can use forkJoin to combine the post and comment observables:

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { forkJoin } from 'rxjs';
import { PostService } from './post.service';
import { Post, Comment } from './post.model';

@Component({
  selector: 'app-post-details',
  templateUrl: './post-details.component.html',
  styleUrls: ['./post-details.component.css']
})
export class PostDetailsComponent implements OnInit {
  post: Post;
  comments: Comment[];

  constructor(
    private route: ActivatedRoute,
    private postService: PostService
  ) {}

  ngOnInit() {
    const postId = +this.route.snapshot.paramMap.get('id');

    forkJoin([
      this.postService.getPost(postId),
      this.postService.getComments(postId)
    ]).subscribe(([post, comments]) => {
      this.post = post;
      this.comments = comments;
    });
  }
}

In the example above:

  • The PostDetailsComponent obtains the post ID from the route parameters using the ActivatedRoute service.
  • Inside the ngOnInit method, we use forkJoin to combine the observables returned by getPost and getComments.
  • The combined observable emits an array containing the post and comment data once both API calls complete.
  • We subscribe to the combined observable and assign the received data to the component properties (post and comments).

Finally, in the component’s template (post-details.component.html), you can display the post and comment information:

<div *ngIf="post">
  <h1>{{ post.title }}</h1>
  <p>{{ post.body }}</p>
</div>

<div *ngIf="comments">
  <h2>Comments</h2>
  <ul>
    <li *ngFor="let comment of comments">
      <h3>{{ comment.name }}</h3>
      <p>{{ comment.body }}</p>
    </li>
  </ul>
</div>

Make sure to import the necessary modules and provide the PostService in your app’s module or component.

getPost
getComments
subscribe
PostService
Post
Comments
forkJoin
Post Comments
PostDetailsComponent

In this diagram:

  • The PostService (A) provides methods to fetch post and comment data from the API.
  • The getPost() method fetches a single post (B) by ID.
  • The getComments() method fetches an array of comments © for a specific post ID.
  • The forkJoin operator (D) combines the observables returned by getPost() and getComments().
  • The combined observable emits an array of the post and comment data.
  • The subscribe() method receives the emitted data (E) and assigns it to the Post and Comments variables in the PostDetailsComponent.

Demo

Next Post Previous Post
No Comment
Add Comment
comment url