I am refactoring some angular code that subscribed to data from a service call. Instead I want the data to be returned from the service as an observable so I can utilize the async pipe so I do not have to unsubscribe from everything at the end. My old code looked something like this:
Component.ts
people: Person[] = [];
getPeople(){
this.apiService.GetPeople().subscribe((result) => {
this.people = result;
}));
}
Then elsewhere I can access the data using this.people
to look through the data and do whatever I need to.
Now I want to do something like the following. But if I do, how do I access the same data within the component without subscribing to the data and having to unsubscribe on ngOnDestroy
Component.ts
people$ = Observable<Person[]>;
getPeople(){
this.people$ = this.apiService.people$;
}
And in my service:
ApiService.ts
private allPeople: BehaviorSubject<Person[]> = new BehaviorSubject<Person[]>([]);
people$ = this.allPeople.asObservable();
With the people$ now being an observable I can do the following in my html:
Index.html
<div *ngIf="people$ | async">
</div>
From what I understand, doing that will automatically unsubscribe as needed. But now that I have the data in the component as people$ which is an observable, how can I access the data? For example, I have an observable of cities and I want to filter them based on whether the observable people are marked with display = true
. I cannot do something like below. So what is the best way to get the same functionality?
Component.ts
let peopleToUse = this.people$.filter(m => m.display === true).map((filter) => {return filter.city});
this.cities$ = this.cities$.filter(m => peopleToUse.includes(m.city));
The end result would be a list of cities that are only in the list of people's city propery where the display = true. Is there a way to do this without subscribing? Because if I subscribe, doesn't it defeat the purpose of the async pipe in the first place?
UPDATE If I have the two observables cities$ and people$, how do I update the cities$ based on changes to people$ ?. For example if the user updates one of the people to have the display = false instead of true, I would want to filter out that record from the cities$.
Example
updatePerson(person: Person){
this.apiService.updatePerson(person);
//update this.cities$ to filter again.
let peopleToUse = this.people$.filter(m => m.display === true).map((filter) => {return filter.city});
this.cities$ = this.cities$.filter(m => peopleToUse.includes(m.city));
}