Home > other >  How to pass parameters while using the async pipe in Angular/rxjs?
How to pass parameters while using the async pipe in Angular/rxjs?

Time:11-03

I'm trying to use the declarative approach in Angular, unwrapping observables with the async pipe and using OnPush change detection.

I have a second observable, which may or may not be invoked, and needs data from the first observable to complete.

order.component.html

<div *ngIf="order$ | async as order">
    <h3> Order {{ order.id }} </h3>
    ....
     
    <app-returns *ngIf="order.status === 'Returned'"
        [rma]="rma$ | async" >
    </app-returns>

</div>

order.component.ts

order$: Observable<Order> = this.route.paramMap.pipe(
   map((params: ParmaMap) =>  params.get('id')),
   switchMap((id: number) => 
       this.orderSvc.get(id)
));

rma$: Observable<Rma> = this.order$.pipe(
    switchMap((order: Order) => 
        this.rmaSvc.get(order.rma.id)
));

This issue with this approach is that the Order service makes two calls to the API to complete this.

When I have multiple observables needed in the template, I'll usually use a forkJoin or combineLatest to combine them. But in this case I only want to call the rma service if necessary.

Other, more naive approaches (while illustrating the issue well) have hilarious outcomes. Can you say 429?

 <app-returns *ngIf="order.status === 'Returned'"
    [rma]="rma$(order.rma.id) | async" >
 </app-returns>

Typescript

rma$(id: number): Observable<Rma> {
    return this.rmaSvc.get(id);
}

How do I pass a parameter while using the async pipe?

CodePudding user response:

you can change your order observable using shareReplay for caching to :

order$: Observable<Order> = this.route.paramMap.pipe(
   map((params: ParmaMap) =>  params.get('id')),
   switchMap((id: number) => 
       this.orderSvc.get(id)
   ),
   shareReplay(1)
);

and then create

rma$: Observable<Rma> = order$.pipe(
  switchMap((order: Order) => 
    this.rmaSvc.get(order.rma.id)
)
  • Related