I have the following stackblitz
https://stackblitz.com/edit/angular-v14-playground-jjpnre?file=src/home.component.ts
It is a simple app where I have a button to fetch async data from an external source.
I'm using async pipe to wait until request is done so it is populated in the textarea
and img
.
I am wondering whether it is possible to use async pipe when I click on the button, so that I won't need to call subscribe
method to get the next value.
CodePudding user response:
Yes you can, the trick is having an event as an observable and doning the rest based on that, without subscribing:
@Component({
imports: [CommonModule, FormsModule, HttpClientModule],
standalone: true,
template: `
<div>
<textarea rows="2" cols="90" [ngModel]="data$ | async">Home</textarea>
</div>
<p><button (click)="onClick()">Click</button></p>
<img src="{{data$ | async }}" />
`,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class HomeComponent implements OnInit {
private click$ = new Subject<void>();
data$ = this.click$.pipe(
switchMap((_) =>
this.httpClient.get('https://dog.ceo/api/breeds/image/random')
),
map((response: DogResponse) => response.message),
startWith('Hello World'), //keeping the functionality in your code, but it doesn't make much sense
share({
connector: () => new ReplaySubject(1), //multiple subscriptions - single get, replay last value
resetOnRefCountZero: true, // reset when no subscriptions (no GET to dog.ceo if no subscription when clicks occur)
})
);
constructor(private httpClient: HttpClient) {}
ngOnInit(): void {}
onClick(): void {
this.click$.next();
}
}