Two ways of using AsyncPipe programmatically
Tags: angular, directives, asyncpipe
Published: 2020-03-02 18:12:13

---
title: Two ways of using AsyncPipe programmatically
published: true
description: AsyncPipe is an angular pipe that helps you resolve an asynchronous value like an observable or a promise to a primitive value.
tags: angular, directives, asyncpipe
---

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/m7cpz1au9gjxh4c9hjzm.png)

## What is AsyncPipe?

AsyncPipe is an angular pipe that helps you resolve an asynchronous value(like an observable or a promise) to a primitive one.

## Common use cases of using AsyncPipe:
Being a pipe it's mostly used on HTML.

## Do I need to subscribe/unsubscribe when I use the AsyncPipe on HTML?

No, the implementation of AsyncPipe will take care of subscribing and unsubscribing.

## How can I use AsyncPipe programmatically in my custom pipes?

Here you can find two ways of using AsyncPipe in your custom pipes:

### 1. Providing `AsyncPipe` and `ChangeDetectorRef` to Dependancy Injection (DI) in your module

You might think that it will just work if you let Dependancy Injection (DI) do the work for you:

```ts
@Pipe({ name: "my_async_pipe" })
export class MyAsyncPipe implements PipeTransform {
  constructor(private asyncPipe: AsyncPipe) {}
  transform(value: any): any {
      return this.asyncPipe.transform(value);
  }
}
```
Above code will not work and will throw an error like:
```ts
ERROR NullInjectorError: StaticInjectorError(AppModule)[ErrorAsyncPipe -> AsyncPipe]: 
  StaticInjectorError(Platform: core)[ErrorAsyncPipe -> AsyncPipe]: 
    NullInjectorError: No provider for AsyncPipe!
  ```
Hmmm seams like `AsyncPipe` has not be added to providers array. Let's fix this error:

- Go to `app.module.ts` 
- Add providers: [AsyncPipe]
- reload
```ts
ERROR NullInjectorError: StaticInjectorError(AppModule)[AsyncPipe -> ChangeDetectorRef]: 
  StaticInjectorError(Platform: core)[AsyncPipe -> ChangeDetectorRef]: 
    NullInjectorError: No provider for ChangeDetectorRef!
```
Another injector not provided, let's repeat the steps above, but this time add `ChangeDetectorRef as Provider`:
- Go to `app.module.ts` 
- This time add providers: [AsyncPipe, ChangeDetectorRef as Provider]
- reload

Success, AsyncPipe has been successfully provided for your custom Pipe.

### 2. Creating a new `AsyncPipe` instance
```ts 
@Pipe({ name: "cdr_async_pipe" })
export class CdrAsyncPipe implements PipeTransform {
  private asyncPipe: AsyncPipe;
  constructor(private cdr: ChangeDetectorRef) {
    this.asyncPipe = new AsyncPipe(this.cdr);
  }
  transform(value: any): any {
    return this.asyncPipe.transform(value);
  }

  ngOnDestroy() {
    this.asyncPipe.ngOnDestroy();
  }
}
```
Using:
 ```ts
 constructor(private cdr: ChangeDetectorRef) {
    this.asyncPipe = new AsyncPipe(this.cdr);
  }
```
The code above creates an instance of AsyncPipe by passing the ChangeDetectorRef as argument.

If you do create your own `AsyncPipe` manually then please don't forget to call `ngOnDestroy()` lifecycle method.

## Which is the best way to use `AsyncPipe` programmatically in your custom pipes?
In my opinion the second one is the best because `DI` will not create two instances of `ChangeDetectionRef` thus no errors like `this._ref.markForChek() is not a function` will be thrown as `ChangeDetectionRef` will be created with one of the classes that extends it.

In the next articles we will look at why when we declare `ChangeDetectionRef` as a provider we get the error `this._ref.markForChek() is not a function`.
 

Article first posted on [danielpdev.io](https://danielpdev.io/use-async-pipe-in-your-custom-pipes/)

[Live example on codesandbox](https://codesandbox.io/s/angular-async-pipe-programmatically-16hpi)

[Follow me on twitter](https://twitter.com/danielpdev)