How to Send Parallel API Calls in Angular

Angular
4 minutes read

Introduction

Hello developers, today we will discuss how to make our Angular apps run faster and smoother. We all know, that when using an app, if it takes too long to load, we might not like it. So, we are going to talk about solving this problem by using something called parallel API calls.

In simple words, when our apps need to collect different pieces of information, doing this one by one can be slow. But with parallel API calls, it’s like having many helpers who are fetching different things all at the same time. This way, our apps can run faster and our users will be happy.

In this article, we will implement both sequential and parallel API calls to see the differences in a practical example (see the full working code from here)

Setting up our project

Starting off, we create a new Angular project. It’s pretty simple, just open up your terminal or command prompt, and type in the following command:

ng new ng-paraller-api-calls

This command asks Angular to create a new project for us named ng-parallel-api-calls. Once you run it, Angular does all the hard work, setting up a new folder with all the files we need!

Now, we make two components – one for the sequential calls and another for the parallel call

ng generate component sequential
ng generate component parallel

By following these steps, we’ve created the base of our Angular project. We’ve got our components, and a helpful service – all set to build upon.

Building the Sequential API Call Component

Now that we’ve got our Angular project up and running, let’s start building our Sequential API Call Component. This component will make one API call, wait for it to finish, and then make the next call.

Let’s start by writing the code for our SequentialComponent. We will use JSONPlaceholder as our mock API for fetching data, as it provides realistic endpoints for testing. Here’s how our component’s TypeScript file will look:

// sequential.component.ts

export class SequentialComponent {
	postData!: PostInterface;
	userData!: UserInterface;
	isLoading = false;

	constructor(private http: HttpClient) {
	}

	ngOnInit() {
		this.isLoading = true;
		this.http.get<PostInterface>('https://jsonplaceholder.typicode.com/posts/1').subscribe(
			(data: PostInterface) => {
				this.postData = data;
				this.http.get<UserInterface>('https://jsonplaceholder.typicode.com/users/1').subscribe(
					(data: UserInterface) => {
						this.userData = data;
						this.isLoading = false;
					},
					(error) => {
						console.error('Error in second API call', error);
						this.isLoading = false;
					}
				);
			},
			(error) => {
				console.error('Error in first API call', error);
				this.isLoading = false;
			}
		);
	}
}

In this code, we are telling our component to fetch some post data first and, once received, fetch some user data. We are also managing a loading state to show whether our component is busy fetching data. Also, we created PostInterface and UserInterface to enhance type safety, ensure data consistency, and reduce runtime errors by catching issues at compile time.

// post.interface.ts

export interface PostInterface {
	id: number;
	userId: number;
	title: string;
	body: string;
}
// user.interface.ts

export interface UserInterface {
	id: string
	name: string
	username: string
	email: string
	address: {
		street: string
		suite: string
		city: string
		zipcode: string
		geo: {
			lat: string
			lng: string
		}
	},
	phone: string
	website: string
	company: {
		name: string
		catchPhrase: string
		bs: string
	}
}

And following is our simple UI

// sequential.component.html

<div *ngIf="isLoading" class="alert alert-info">Loading data...</div>

<div *ngIf="!isLoading" class="row">
	<div class="col-md-6">
		<div class="card mb-3">
			<div class="card-header fw-bold">Post Data</div>
			<div class="card-body">
				<h5 class="card-title">{{ postData.title }}</h5>
				<br>
				<p class="card-text">{{ postData.body }}</p>
			</div>
		</div>
	</div>

	<div class="col-md-6">
		<div class="card mb-3">
			<div class="card-header fw-bold">User Data</div>
			<div class="card-body">
				<h5 class="card-title">{{ userData.name }}</h5>
				<br>
				<p class="card-text"><strong>Username:</strong> {{ userData.username }}</p>
				<p class="card-text"><strong>Email:</strong> {{ userData.email }}</p>
				<p class="card-text"><strong>Phone:</strong> {{ userData.phone }}</p>
				<p class="card-text"><strong>Address:</strong> {{ userData.address.street }}
					, {{ userData.address.city }}</p>
			</div>
		</div>
	</div>
</div>

The problem

While this approach is quite straightforward, it has a few downsides:

  • Performance: Since we are waiting for the first call to complete before making the second, it takes more time.
  • Readability: The code becomes harder to read as we nest more calls inside each other.
  • Error Handling: If any call fails, managing errors becomes tricky, especially when we have several nested calls.

Building the Parallel API Call Component

Let’s explore how to build the Parallel API Call Component in Angular. This approach allows us to send multiple requests at the same time, making our app faster and more efficient.

To begin, we’ll make parallel API calls using a handy tool in Angular called forkJoin. forkJoin is an RxJS operator that “Wait for Observables to complete and then combines the last values they emitted”. In other words, forkJoin allows you to wait for multiple Observables to complete and then emit their latest values as an array.

Here’s the code snippet for our ParallelComponent:

// parallel.component.ts

export class ParallelComponent implements OnInit {

	postData!: PostInterface;
	userData!: UserInterface;
	isLoading = false;

	constructor(private http: HttpClient) {
	}

	ngOnInit() {
		this.isLoading = true;

		forkJoin({
			postData: this.http.get('https://jsonplaceholder.typicode.com/posts/1'),
			userDate: this.http.get('https://jsonplaceholder.typicode.com/users/1')
		}).subscribe(
			(results: any) => {
				this.postData = results.postData;
				this.userData = results.userDate;
				this.isLoading = false;
			},
			(error) => {
				console.error('Error in API calls', error);
				this.isLoading = false;
			}
		);
	}
}

We will use the same UI as in SequentialComponent

In this approach, forkJoin helps us make API calls in parallel. We’re not waiting for the first call to complete to start the next one. Instead, we’re kicking off both at the same time!

Advantages Over the Sequential Approach

This parallel method comes with several benefits:

  • Speed: Because we’re not waiting around, our app gets the data faster.
  • Readability: The code is cleaner and easier to understand, without the nesting.
  • Error Handling: Managing errors is simpler since forkJoin helps us catch issues in any of the calls.

Demonstrating the Performance Improvement

When you run both components, you’ll notice that the ParallelComponent fetch and display data noticeably faster than the SequentialComponent. This speed-up is because we’re not waiting for one task to finish to start the next, showcasing the efficiency of parallel API calls.

Further Reading

Conclusion

In conclusion, we looked at how making one call at a time can slow us down. It’s like waiting in a long line. But, by using parallel API calls, we can speed things up! We used something called forkJoin in Angular to do many things at once. This change made our app faster. The code is now easier to read and manage.

So, to all the developers reading, think about using parallel API calls in your Angular apps. It’s a way to make your apps better and your coding more fun. Happy coding!

Leave a Reply

Your email address will not be published. Required fields are marked *