When I call an async pipe in an element to be iterated, will it be created a single shared subscription or multiple?

Viewed 150

Got a quick question about how Angular handles async pipes: given the following block of code, if I were to call a function inside an element that will be rendered N times and pass it the value of an observable as a parameter using an async pipe, will the subscription that's passed to these function executions be shared or will these be independent subscriptions?

<ng-container *ngFor="...">
  <div>{{ getSomeValue(myObservable$ | async) }}</div>
</ng-container>

Thanks!!

2 Answers

Each async piping will result in a new subscription. Therefore to avoid unnecessary subscriptions, you can use the *ngIf approch

<ng-container *ngIf="(myObservable$ | async) as myValue">
    <ng-container *ngFor="...">
       <div>{{ getSomeValue(myValue) }}</div>
    </ng-container>
</ng-container>

myObservable$ | async will evaluate and bind to the value of myValue, then it is available to use without further subscription within the template sub-tree.

Beyond the normal answer, DON'T CALL METHODS WITH ASYNC VALUES

Every time a change detection happens it will subscribe and unsubscribe to all of the observables again and again. You either use noam's answer or you can try mapping the list if need be

public list$ = this.myObservable.pipe(map(obsValue => this.array.map(row => this.getSomeValue(obsValue)));

This would be much better performance wise because otherwise angular calls your getSomeValue 10 times a second.

Related