Previously, I wrote about how to use the async pipe to automatically subscribe and unsubscribe from our observables.
When I teach that topic, people usually have at least one of these two objections:
What if I also need the data from that subscription in my Typescript code?
At first, using the async pipe seems only to give you access to the data in your HTML templates. That isn’t the case, though, because you can still use the tap operator to “spy” on your observable and get the data from there. For instance (complete example here):
this.name$ = nameService.getName().pipe(
tap(name => this.name = name)
);Code language: TypeScript (typescript)
And then in the HTML template:
<p>Name from async pipe: {{ name$ | async }}</p>Code language: HTML, XML (xml)
What if I need to read multiple properties from the object in that subscription?
Another way to put it is that you don’t want to end up doing something like this:
<p>First name: {{ (user$ | async)?.firstName }}</p>
<p>Last name: {{ (user$ | async)?.lastName }}</p>Code language: HTML, XML (xml)
The above code is pretty hard to read and requires one subscription for each property. This alone can be a disaster, as each subscription might trigger an HTTP request for the same data from the server!
Instead, you can do something like this, which uses only one subscription, stores the result in a local variable, then renders the data when it’s available:
@let user = user$ | async;
<div>
<p>First name: {{ user.firstName }}</p>
<p>Last name: {{ user.lastName }}</p>
</div>Code language: JavaScript (javascript)

