I'm new to angular and struggle a little with rxjs and all the async stuff going on.
Lets assume you have a website like facebook with profiles. You can reach a profile by navigating to website.com/profiles/profileUrl
. Equally when clicking on a profile, you get routet to the profiles/:profileUrl
in Angular terms.
I route to the PersonProfileComponent
and retrieve the profile data from a backend, both based on the profileUrl
:
Component:
export class PersonProfileComponent implements OnInit {
person: Observable<PersonTO>;
constructor(private route: ActivatedRoute,
private mockDataService: MockPersonService) {}
ngOnInit() {
this.route.params.subscribe(params => {
this.initializePerson(params['profileUrl']);
});
}
initializePerson(profileUrl: string) {
this.mockDataService.getFullPersonByProfilUrl(profileUrl).
subscribe(foundPerson => {
this.person = of(foundPerson);
});
}
}
Template:
<p>
profile works {{(person | async)?.profileUrl}}!
</p>
While everything works, I do dislike mostly this part in the template "(person | async)?.profileUrl
". The person object can get pretty large with many attributes, I cannot imagine accessing each and every attribute like this. It just doesn't feel right. Is there a way around this while still using the async pipe, as this handles all the subscribing and unsubscribing for me? Furthermore, I'm thankful to any criticism regarding this snippit and how to implement it better!
ok you have 2 options here one to use once async pipe in template and add alias for it
<div *ngIf="(person | async) as personObj">
<p>
profile works {{personObj.profileUrl}}!
name {{personObj.name}} // and so on
</p>
</div>
another option is to subscribe in component and save person object in a property inside subscription and use that property in template.
NOTE that you need to check that property in template with *ngIf
because on init it will be undefined since it will be assigned asynchronously, and don't forget to unsubscribe too