Reputation: 2813
I have an Observable, which returns a large object from an API. I need to display these values in my template.
For other data returned as an array, I can use:
<div *ngFor="let value of values | async">
<p>{{ value.prop }}</p>
</div>
I don't need to wait for the async to complete within the *ngFor
, as it's already got an async pipe in the parent element.
With my object, I'm looking for something similar. At the moment, I'm doing something like:
<h2>{{ (obj | async)?.title }}</h2>
<p>{{ (obj | async)?.prop.prop2 }}</p>
<p>{{ (obj | async)?.another.prop }}</p>
This obviously leaves a lot of duplicate code. Does something like this exist?
<div *using="obj | async">
<!-- obj has resolved, can access obj.prop -->
</div>
Upvotes: 3
Views: 8725
Reputation: 17889
Use 'as' syntax.
Also be aware that each async pipe creates a new subscription and if you subscription uses http - it means multiple http calls. Use Rx share() if you want to use the same observable multiple times in template with async pipe.
@Component({
selector: 'my-app',
template: `
<div>
<div *ngIf="obj$ | async as obj; else empty">
{{obj.x}}
{{obj.y}}
</div>
<ng-template #empty>Empty. Wait 5 s...</ng-template>
</div>
`,
})
export class App {
s = new Subject();
obj$;
constructor() {
this.obj$ = this.s.asObservable();
setTimeout(() => {
this.s.next({x:12, y:100});
}, 5000)
}
}
Upvotes: 7
Reputation: 91
You could create a alias like this:
<div *ngIf="(obj$ | async) as obj">
<h2>{{ obj?.title }}</h2>
<p>{{ obj?.prop.prop2 }}</p>
<p>{{ obj?.another.prop }}</p>
</div>
Upvotes: 4