AsyncPipe is an angular pipe that helps you resolve an asynchronous value(like an observable or a promise) to a primitive one.
Being a pipe it’s mostly used on HTML.
No, the implementation of AsyncPipe will take care of subscribing and unsubscribing.
Here you can find two ways of using AsyncPipe in your custom pipes:
AsyncPipe and ChangeDetectorRef to Dependancy Injection (DI) in your moduleYou might think that it will just work if you let Dependancy Injection (DI) do the work for you:
@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:
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 it:
app.module.tsERROR 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:
app.module.tsSuccess, AsyncPipe has been successfully provided for your custom Pipe.
AsyncPipe instance@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:
constructor(private cdr: ChangeDetectorRef) {
this.asyncPipe = new AsyncPipe(this.cdr);
}We are manually creating 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.
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.
