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.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
:
app.module.ts
Success, 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
.