'Create custom pipe that is async by itself
I've created a custom pipe that retrieves bits of textual content from an API, like this:
@Pipe({ name: 'apiText' })
export class ApiTextPipe implements PipeTransform {
constructor(private myApiService: MyApiService) {
}
transform(key: string): Observable<string> {
return this.myApiService.getText(key);
}
}
I have to use it like this:
<strong>{{'some-key' | apiText | async}}</strong>
But effectively I will always want to combine the apiText and async pipes. I'd prefer to write this:
<strong>{{'some-key' | apiTextAsync}}</strong>
Can I do that somehow, and make things a bit more DRY by combining the two pipes?
UPDATE 1: I've opened a GitHub issue as a feature request for a solution for this.
UPDATE 2: The issue was closed because the async pipe "is not special" and "nothing prevents you from writing one that is similar 🤷♂️
Solution 1:[1]
There's no need to duplicate the source of the async pipe-transform, the only things you really need are the pure: false property and the ChangeDetectorRef.
Here is a small minimal example for it:
import { ChangeDetectorRef, Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'example',
pure: false
})
export class ExamplePipeTransform implements PipeTransform {
value?: string;
constructor(private _ref: ChangeDetectorRef) {}
transform(value: any): unknown {
if (!this.value) {
this.value = value;
setTimeout(() => {
this.value = value;
this._ref.markForCheck();
}, 1000);
}
return this.value;
}
}
Once the asynchronous operation you want to do is done, you store the value and simply call ChangeDetectorRef.markForCheck. This will cause transform to be called again.
Instead of the setTimeout you can for example Observable.subscribe and then return the resolved value.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | maxdev |
