Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to remove specific element from Observable<Array<any>>

There is an Observable of the array of places:

places: Observable<Array<any>>;

In template it used with the async pipe:

<tr *ngFor="let place of places | async">
  ...
</tr>

After some user actions I need to remove the place with specific id from this array. I have something like this in my code, but it doesn't work:

deletePlace(placeId: number): void {
  this.apiService.deletePlace(placeId)
  .subscribe(
    (res: any) => {
      this.places
        .flatMap((places) => places)
        .filter((place) => place.id != placeId);
    }, 
    (err: any) => console.log(err)
  );    
}  

Can you help me with this?

like image 686
daslashi Avatar asked Jul 04 '16 10:07

daslashi


Video Answer


2 Answers

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:

  • one for the initial loading
  • another one for the delete event.

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.

like image 116
Thierry Templier Avatar answered Sep 27 '22 17:09

Thierry Templier


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));
like image 23
Tecayehuatl Avatar answered Sep 27 '22 18:09

Tecayehuatl