I have a component where I am using a service to fetch data that also has a search filter
I would like the Observable to be the end result of the HttpClient with the filter applied from the FormControl searchControl so that reportPeriods$ is a stream of the filtered result
This works but I am noticing that my map function is firing N times for each item that exists in ReportPeriod[] and I am not sure this is the correct usage
The request to fetch getReportPeriods(12) should only fire once
export class ReportPeriodComponent {
reportPeriods$: Observable<ReportPeriod[]>;
searchControl = new FormControl<string>('');
private destroyRef = inject(DestroyRef);
constructor(public qaService: QaService, private reportPeriodService: ReportPeriodService) {
this.reportPeriods$ = combineLatest({
reportPeriods: this.reportPeriodService.getReportPeriods(12),
text: this.searchControl.valueChanges.pipe(startWith(''))
}).pipe(
takeUntilDestroyed(this.destroyRef),
map(({ reportPeriods, text }) => {
if (text && text.length > 0) {
return reportPeriods.filter((reportPeriod) => reportPeriod.friendlyName.toLowerCase().indexOf(text.toLowerCase()) !== -1);
} else {
return reportPeriods;
}
})
);
}
}
ReportPeriodService
getReportPeriods(monthsAgo: number): Observable<ReportPeriod[]> {
let params = new HttpParams().set('monthsAgo', monthsAgo);
return this.http.get<ReportPeriod[]>(`${this.url}/report-periods`, { params }).pipe(
map((reportPeriods) => {
return reportPeriods
.map((reportPeriod) => {
return {
...reportPeriod,
startDate: new Date(reportPeriod.startDate),
endDate: new Date(reportPeriod.endDate)
};
})
.sort((a, b) => b.endDate.getTime() - a.endDate.getTime());
})
);
}


switchMap is the perfect operator to solve something like this, I will also say the reason for the observable appearing to fire duplicate times if because I was also referencing that observable with an async pipe in the *ngFor of my template