2

I have a service with a delete function. The delete function will call an api and it will return true or false. When true, I will lookup the index in my array, splice it and return the new array. So for example

private items = [];
onItemDeleted  = new Subject<any>();

  delete(id:number): Observable<any> {
    return this.http.delete('http://my.api.com/item/' + id)
      .pipe(
        switchMap(checkServerSuccessResponse),
        map(data => {
            const index1  = this.items.findIndex((element) => {
              return element.id === id;
            });
            if (index1 >= 0 ) {
              this.items.splice(index1,1);
            }
            this.onItemDeleted.next(this.items);
            return this.items;
          }
        ),
        catchError(returnFalse),
      );
  }

I have a helper for the switchmap :

export function checkServerSuccessResponse(data: Response): Observable<any> {
    return (data && data['success'] === true) ? of(data) : throwError("server responded false");
}

Although this works, I have a feeling the map section can reformatted. I first thought of filter (after the switchmap) to exclude the element with the id I've supplied, then emit the new array, but then I realised, the filter is not subscribed to the this.items array.

What would be the best approach to do this?

2
  • I don't know you other code, for example where this.items coming from, why do you publish updated items to onItemDeleted. But I would probably: a) pass this.items to delete method also like delete(id, items) because on the time when response will arrive, you don't know what will happen with this.items; b) that thing within the map, move to separate function, that will be removeById(items, id); c) pipe will become switchMap(checkServerSuccessResponse), map(removeById), tap(onItemDeleted.next), catchError(returnFalse) (calls abbreviated to fit to this comment). Commented Oct 30, 2018 at 9:35
  • Moving the logic for the delete in removeById function that is what I also want. But what I dont understand is the map(removeById). Because in the stack of the pipe, the first argument is the response from the api call (checkServerSuccessResponse helper) and not the this.items array Commented Oct 30, 2018 at 10:30

1 Answer 1

1

I don't know you other code, for example where this.items coming from, why do you publish updated items to onItemDeleted. But I would probably: a) pass this.items to delete method also like delete(id, items) because on the time when response will arrive, you don't know what will happen with this.items; b) that thing within the map, move to separate function, that will be removeById(items, id); c) simplify pipe. Like this:

private items = [];
onItemDeleted  = new Subject<any>();

  removeById(fromItems, id) {
    const index1  = fromItems.findIndex((element) => {
      return element.id === id;
    });
    if (index1 >= 0 ) {
      fromItems.splice(index1,1);
    }
    return fromItems;
  }

  // who ever calls this, should provide copy of items also
  // then you will be kinda protected from concurrent
  // modification, when http response complete, but this.items
  // is completely different, from when http request started
  delete(fromItems, id:number): Observable<any> {
    return this.http.delete('http://my.api.com/item/' + id)
      .pipe(
        switchMap(checkServerSuccessResponse),
        map(data => this.removeById(fromItems, id)),
        tap(items => this.onItemDeleted.next(items)),
        catchError(returnFalse),
      );
  }
Sign up to request clarification or add additional context in comments.

3 Comments

ugh .. makes so sense right now .. I was to stuck to map the function directly to the removebyid function.
pipe is great to express what you want to do, if possible with one liners, becomes much more readable :)
hehe yes .. thank you .. I was so stuck in my mind .. got it working now, even as a global helper function :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.