3

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?

1 Answer 1

2

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 your rma observable using switchMap

rma$: Observable<Rma> = order$.pipe(
  switchMap((order: Order) => 
    this.rmaSvc.get(order.rma.id)
)
Sign up to request clarification or add additional context in comments.

1 Comment

Fits the bill- clean, declarative approach and only hits the API once. Thanks!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.