I have a simple todo list that when clicking on "complete", it should remove that item from the list, but nothing seems to be happenning when clicking on it.
Stackblitz: Link
HTML:
<div *ngIf="list$; else noList">
<div *ngFor="let data of list$ | async" class="items">
<div>{{ data.id }} -</div>
<div>{{ data.description }}</div>
<button (click)="complete(data)">Complete</button>
</div>
</div>
<button (click)="add()">Add</button>
<ng-template #noList>
<h1>Loading...</h1>
</ng-template>
service:
complete(data: any) {
console.log(data.id);
let result = this.data$
.pipe(
filter((x: any) => x.id !== data.id),
tap((x: any) => console.log(x))
)
.subscribe((val: any) => {
this.resultObs = of(val);
console.log(val);
console.log(this.resultObs);
});
return this.resultObs;
}
The filter
pipe operator does not itself filter arrays. It filters data going through the pipe. If you have this:
arr$: Observable<any[]> = of([1, 2]);
arr$.pipe(
filter((x) => . . .)
)
x
in the filter
function will be the entire [1, 2]
array, not each element of the array. filter
here filters the entirety of data coming through the pipe. You could use it, for example, to prevent the subscribe
callback from running unless the user had more than 4 todos:
arr$: Observable<any[]> = of([1, 2]);
arr$.pipe(
filter((todos: any[]) => todos.length > 4)
).subscribe(() => {
console.log("Will not run")
});
arr$.pipe(
filter((todos: any[]) => todos.length < 4)
).subscribe(() => {
console.log("Will run, since the length of the array is less than 4")
});
If you want to transform the object going through the pipe, you'd use map
:
let result = this.data$
.pipe(
map((xs: any[]) => xs.filter((x) => x.id !== data.id)),
tap((xs: any[]) => console.log(x))
)
.subscribe((val: any) => {
this.resultObs = of(val);
console.log(val);
console.log(this.resultObs);
});
This transforms the array held by data
using map
, by calling the filter
method on the array to do the filtering.