Home > Mobile >  Angular: Use async pipe in button click
Angular: Use async pipe in button click

Time:09-06

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();
  }
}
  • Related