Angular HTTP best practices (AsyncPipe)
Tags: angular, javascript, reactiveextensions
Published: 2020-02-24 09:52:27

---
title: Angular HTTP best practices (AsyncPipe)
published: true
date: 2020-02-21 09:14:39 UTC
tags: Angular, Javascript, Reactive Extensions
canonical_url: https://yon.fun/angular-http-best-practices/
---

![Angular HTTP best practices (AsyncPipe)](https://yon.fun/content/images/2020/01/angular-http-async-req.png)

In this article, we'll cover some best practices to **create HTTP requests just using the Angular AsyncPipe.** If you ever thought about making HTTP requests without calling `.subscribe()`, then you're on the right page.

## Why AsyncPipe?

According to Angular [AsyncPipe](https://angular.io/api/common/AsyncPipe) documentation:

> The `async` pipe subscribes to an `Observable` or `Promise` and returns the latest value it has emitted. When a new value is emitted, the `async` pipe marks the component to be checked for changes. When the component gets destroyed, the `async` pipe unsubscribes automatically to avoid potential memory leaks.

The most important part here is "when the component gets destroyed, the 
 [`async`](https://angular.io/api/common/api/core/testing/async) pipe unsubscribes automatically to avoid potential memory leaks." These being said, we don't have to worry about **unsubscribing** the Observables, the AsyncPipe will take care for of it us - good practice (and the most important).

## The Observables

Let's create some observables and get started:

<!--kg-card-begin: code-->

```js
private onDestroy$ = new Subject<boolean>();
user$ = new BehaviorSubject<{ id: number, name?: string }>(null);
```
<figcaption>Create new <strong>Subject</strong> and source <strong>BehaviorSubject.</strong></figcaption>

<!--kg-card-end: code-->

As you can see, I defined two Observables, `onDestroy$` and `user$`. It's a good practice to have an observable which will be called when the component gets destroyed, but I'll talk later more about it.

Based on `user$` BehaviorSubject, we'll create **a new Observable** `getUserInfo$` which sends a server request - each time the `user$` gets emitted:

<!--kg-card-begin: code-->
```js
  getUserInfo$: Observable<IUser> = this.user$.pipe(
    exhaustMap(user => user && this.http.get(user.id).pipe(
      map(...),
      tap(...)
    ) || of(null)),
    takeUntil(this.onDestroy$),
  );
```
<!--kg-card-end: code-->

<figcaption>Create a new <strong>Observable</strong> from <strong>BehaviorSubject.</strong></figcaption>

If you don't understand what's going on in this code and the `.pipe` function is unclear for you, maybe you should first take a look at [this article](https://www.learnrxjs.io/learn-rxjs/concepts/rxjs-primer#pipe) and then continue reading!

There are two **Operators** to pay attention, `exhaustMap` and `takeUntil`. Of course, you can add more operators, but _these two are the most important_.

Using an `exhaustMap` operator we can be sure that `getUserInfo$` **will always wait for the server response**, even if the `user$` emits a new value, it's the opposite of the `switchMap` operator. See the picture below:

<!--kg-card-begin: image-->

![Angular HTTP best practices (AsyncPipe)](https://yon.fun/content/images/2020/02/12-exhaustMap-before.png)<figcaption>RxJs exhaustMap operator. Credits <strong>Angular University.</strong></figcaption>

<!--kg-card-end: image-->

You can read more about [RxJs Mapping here](https://blog.angular-university.io/rxjs-higher-order-mapping/), to have a better idea of why we used `exhaustMap` and not other mapping operators.

`takeUntil` subscribes and begins mirroring the `user$` Observable. It also monitors a second Observable, `this.onDestroy$` that we provided. If the `this.onDestroy$` emits a value, the `getUserInfo$` Observable stops mirroring the `user$` Observable and complete. For more info about `takeUntil`, see the [official documentation](https://rxjs.dev/api/operators/takeUntil).

## Subscribing via Angular AsyncPipe

Now as we created the `getUserInfo$` Observable, let's see how to subscribe to it using **AsyncPipe** :

<!--kg-card-begin: code-->

```html
<ng-container *ngIf="getUserInfo$ | async as user">
	{{ user | json }}
</ng-container>
```
<!--kg-card-end: code-->

<figcaption>Use Angular <strong>AsyncPipe</strong> to subscribe to the <em>getUserInfo$</em>.</figcaption>

And then just emit a new value for `user$` in order to trigger the server request:

<!--kg-card-begin: code-->

```html
<button mat-icon-button (click)="user$.next({ id: 2, name: 'John Doe' })">
    Get user with id 2
</button>
```
<!--kg-card-end: code-->

<figcaption>Emit new <em>user info,</em> to trigger a server request.</figcaption>

Now, if we click the button, even if we double-click, the `getUserInfo$` will send a server request and emit new _user info_ which will be handled by Angular **AsyncPipe** and in turn, will insert new _user info_ into the page.

As we use `takeUntil` operator, we have to emit some value for `this.onDestroy` as well as complete it, `takeUntil` is optional here, as we subscribed to `getUserInfo$` via Angular **AsyncPipe** which takes care of _unsubscribing when element gets destroyed_, but anyway, it's **a good practice and it's good to know about it**.

<!--kg-card-begin: code-->

```js
  ngOnDestroy() {
    this.onDestroy$.next(true);
    this.onDestroy$.complete();
  }
```
<figcaption>Make sure we <strong>unsubscribe from Observable</strong> when <strong>component gets destroyed</strong>.</figcaption>

<!--kg-card-end: code-->
## Conclusion

Now we don't have to worry about memory leaking, as we did the best practices for subscribing and unsubscribing from Observables. We can be sure that our code will work faster as **AsyncPipe** allows us to change the `changeDetection` of our component to `ChangeDetectionStrategy.Push`, which (after me) is the best way to optimize a component and as well a good practice.

Haven't you tried yet? Try it and let me know how it works for you 💻.