IvanS95
IvanS95

Reputation: 5742

Proper approach for Async Pipe

I'm building an Angular app and trying to use the async pipe whenever possible to handle Observable suscriptions.

I'm still to exactly sure of when and why I should use it, most of the time I've seen that if I don't need to make any changes to the coming data I can just use it and show the data as-is; but if I need to to something to any piece of the data beforehand I should manually subscribe in my typescript code and handle everything there before displaying it.

So for example if I have an array of objects and I need to manipulate a string in one of the object's properties it would be better to manually subscribe, handling the response and then displaying that in my template.

Is this assumption correct?

Upvotes: 1

Views: 120

Answers (1)

Andrew Halil
Andrew Halil

Reputation: 1319

I have used both types of observables within components and these are my reasons (there are probably others that I am not aware of):

Reasons for using a subscribed observable:

  1. To control subscribing and unsubscribing subscriptions manually.
  2. Synchronizing the loading and manipulation of data within a component before internal use.
  3. When the subscribed data is used internally (non-visually) within the component, such as a service or computations.

Reasons for using an asynchronous observable pipe:

  1. Subscribing and unsubscribing of subscriptions of observables is handled automatically.
  2. Synchronizing the loading and manipulation of data within a component before use within the HTML template.
  3. When there are a number of HTML elements that depend on subscribed data and you would like the subscriptions released automatically after the component is destroyed.

In both cases you can load and manipulate subscribed data within your component before usage.

An example of each is below:

Subscription based

TS

someData: SomeClass[] = [
  { id: 1, desc: 'One', data: 100 },
  { id: 2, desc: 'Two', data: 200 },
  { id: 3, desc: 'Three', data: 300 }
];
someData$: Observable<SomeClass[]>;

this.someData$ = of(this.someData).subscribe((res) => {
  this.someData = res.map((r) => {
    r.data = Math.floor(r.data * 1.1);
    return r;
  });
});

Asynchronous observable pipe

TS

...
someData: SomeClass[] = [];
someData$: Subscription;

this.someData$ = of(this.someData).pipe(
  map((res) => {
    res.map((r) => {
      r.data = Math.floor(r.data * 1.1);
    });
    return res;
  })
);

HTML (for both options)

<li *ngFor="let data of someData$ | async">
  Item={{ data.desc }}. Value={{ data.data }}
</li>

To summarize, the usage of either option depends on the complexity of your component, it's type (visual or non-visual) and how you would like to manage the memory management of subscriptions.

The answer to the original question is no, it is not necessarily better to manually subscribe when calculations/pre-processing are involved. You can also use an asynchronous pipe to do likewise as I showed with the two equivalent examples above.

Upvotes: 2

Related Questions