I am kind of new at angular and I am doing an application to learn better. I have a problem about binding and filtering results of a http call. At below code I try to bind a list of some data.
At service I have a call like this
getTestFields(): Observable<Engagement[]> {
return this.httpClient.get<Engagement[]>(this.url + '/testFields');
}
It basically returns a list of some test fields; and at component.ts I am binding the results of call to an observable variable.
dataSet$: Observable<Engagement[]>;
ngOnInit(): void {
this.dataSet$ = this.service.getTestFields();
}
And at the html template I bind the data like below:
<table class="table table-hover" *ngIf="dataSet$ | async as resultSet; else loading">
<tr *ngFor="let item of resultSet" >
<td>{{item.testName}}</td>
<td>{{item.planned}}</td>
<td>{{item.workingOn}}</td>
<td>{{item.reviewed}}</td>
</tr> </table>
Until here I have no problem; I get the data successfully and show in table. The problem is filtering; I couldn't figure out how I can filter the data that I already got from server. I don't want to make server calls for filtering data, I want to filter the current list that I already got.
I tried something like below but it didn't work.
filter() {
this.dataSet$ = this.dataSet$.pipe(
switchMap(data => {
return data.filter(p => p.planned)
})
);
}
How can I filter existing observable list without sending a new call to server ?
Try the rxjs map
operator coupled with array filter
.
Map transforms the observable, so in this case we are using it to transform the array to only include the items where planned
is true.
import { map } from 'rxjs/operators';
.....
ngOnInit(): void {
this.dataSet$ = this.service.getTestFields().pipe(
map(data => data.filter(p => p.planned)),
);
}
You can also filter
emissions from the Observable using the filter
operator of rxjs
but I don't think you need it in this case.
================ Use of RxJS Filter ===================
import { filter } from 'rxjs/operators';
...
ngOnInit(): void {
this.dataSet$ = this.service.getTestFields().pipe(
// make sure data is truthy and has a length before emitting to
// the consumer (in this case it is the HTML).
filter(data => !!data && !!data.length),
);
}