There is an Observable of the array of places:
places: Observable>;
In template it used with the async pipe:
The filter function is immutable and won't change the original array.
I would change the deletePlace function to something like this:-
deletePlace(placeId: number): void {
this.apiService.deletePlace(placeId)
.subscribe(
(res: any) => {
this.places = this.places.filter((place) => place.id != placeId);
},
(err: any) => console.log(err)
);
}
RxJS version 6
Using the accepted answer with RxJS 6 and typescript
will throw an error because the observables
hold different types. you better use combineLatest
, you could also use zip
but it will not work! did you just ask why? the answer is here :)
combineLatest([
this.items$,
this.deleteItem$
]).pipe(
takeUntil(this.onDestroy),
tap(([items, deleteItem]) => {
if (deleteItem && deleteItem.op === 'deleteItem') {
var index = items.findIndex((item) => item.id === deleteItem.id);
if (index >= 0) {
items.splice(index, 1);
}
return items;
}
else {
return items.concat(deleteItem);
}
})
).subscribe();
then you can send the event..
this.deleteItem$.next({ op: 'deleteItem', id: '5e88fce485905976daa27b8b' });
I hope it will help someone..
You can take advantage of filter operator:
this.places$
.pipe(
map(places => {
// Here goes some condition, apply it to your use case, the condition only will return when condition matches
return places.filter(place => place.placeId !== 0);
}),
map(response => (this.users$ = of(response)))
)
.subscribe(result => console.warn('Result: ', result));
You can't do it this way since you can't "update" an observable (i.e. it doesn't keep states) but you can react to an event through it.
For your use case, I would leverage the scan
operator and merge two streams into a single one:
Here is a sample:
let obs = this.http.get('/data').map(res => res.json());
this.deleteSubject = new Subject();
this.mergedObs = obs.merge(this.deleteSubject)
.startWith([])
.scan((acc, val) => {
if (val.op && val.op==='delete') {
var index = acc.findIndex((elt) => elt.id === val.id);
acc.splice(index, 1);
return acc;
} else {
return acc.concat(val);
}
});
To trigger an element deletion, simply send an event on the subject:
this.deleteSubject.next({op:'delete', id: '1'});
See this plunkr: https://plnkr.co/edit/8bYoyDiwM8pM74BYe8SI?p=preview.