Angular Routing and RxJs subscription sharing

LppEdd

Edit: apparently the shareReplay approach works fine too. I don't understand why however, given the description of the operator. If someone is so kind to explain why, it will be much appreciated.


I currently have a Component, managed via routing, with a template that looks like

<app-one [attr]="entity$ | async"></app-one>
<app-two
  [attrOne]="(entity$ | async)?.id"
  [attrTwo]="(entity$ | async)?.name"
></app-two>

The Component code is

export class EntityComponent implements OnInit {
  entity$: Observable<Entity>;

  ...

  ngOnInit() {
    this.entity$ = this.route.paramMap.pipe(
      map(params => params.get('entityId')),
      mergeMap(entityId => this.service.getEntity(entityId))
    );
  }

Being that I use the async pipe three times, the service.getEntity is called three times (I can see three HTTP calls).

How can I mitigate this problem?
Is adding shareReplay(1)

this.entity$ = this.route.paramMap.pipe(
  map(params => params.get('entityId')),
  mergeMap(entityId => this.service.getEntity(entityId)),
  shareReplay(1)
);

an acceptable solution? I don't think so, as it will mess up routing.

Edit: my components are all OnPush, and subscribing and storing the result as a class property would mean having to detectChanges, which I don't like at all.

dcg

I think you could wrap your two components with a ng-container applying the async pipe and store the result in a variable and then use that in the components, something like:

<ng-container *ngIf="entity$ | async as entity"
    <app-one [attr]="entity"></app-one>
    <app-two
          [attrOne]="entity?.id"
          [attrTwo]="entity?.name"
    ></app-two>
</ng-container>

Update What I mean is that you are able to do something like:

this.entity$ = new Observable<Entity>(observer => {
    observer.next(null);
    this.route.paramMap.pipe(
        map(params => params.get('entityId')),
        mergeMap(entityId => this.service.getEntity(entityId)),
    ).subscribe(e => {
        observer.next(e);
        observer.complete();
      }, () => {
        observer.complete();
      });
});

Hope it helps!

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

Rxjs Sharing an observable subscription

angular rxjs subscription teardown

Angular + rxjs: No provider for Subscription

Angular RxJS Subscription Reference Value

Angular 10, rxjs - looping on subscription?

Angular RxJS Subject subscription and unsubsciption

angular 2 routing subscription change detection

Rxjs Subscription does not work in a Angular Directive

Angular rxjs: keep subscription after error reached

Angular listen on subscription start of rxjs observable?

Angular 5 RxJS Subscription Timing Issue

Angular 5 & Rxjs: Wait for all subscription

Initialization of rxjs observables, switchMap with Angular routing

angular - show loading while rxjs subscription waits for data

Angular RxJS Observable: takeUntil vs. unsubscribe with a Subscription

Angular/RxJs When should I unsubscribe from `Subscription`

Type 'Observable<Subscription>' is not assignable to type Observable<MyData> rxjs angular

Angular6 rxjs unsubscribing to timer subscription OnDestroy does not work?

RxJs Subscription does not get fired in the root angular module

Angular2 + RxJS BehaviorSubject subscription not working on all components

Angular 7 Rxjs - In-Flight HTTP request not cancelling for subscription

A better code maintenance for identical subscription handling code [Angular/Rxjs]

RxJS, Angular: Cannot receive result of subscription in other methods

What's the problem in that Angular 7 rxjs subscription from a resolver

Angular rxjs: Delay subscription till other Observable emits

RxJs / Angular: Fetch additional data via subscription inside a map loop

Error method on Angular rxjs subscription not beeing executed at all

Debounce and buffer an rxjs subscription

Rxjs subscription queue