У меня есть сервис с функцией удаления. Функция удаления вызовет api и вернет true или false. Если это правда, я ищу индекс в моем массиве, объединяю его и возвращаю новый массив. Так например
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),
);
}
У меня есть помощник для карты переключателей:
export function checkServerSuccessResponse(data: Response): Observable<any> {
return (data && data['success'] === true) ? of(data) : throwError("server responded false");
}
Хотя это работает, у меня есть ощущение, что раздел карты можно переформатировать. Сначала я подумал о фильтре (после карты переключателей), чтобы исключить элемент с указанным мной идентификатором, а затем создать новый массив, но затем я понял, что фильтр не подписан на массив this.items.
Как лучше всего это сделать?
Я тоже хочу перенести логику удаления в функцию removeById. Но я не понимаю карту (removeById). Поскольку в стеке канала первым аргументом является ответ от вызова API (помощник checkServerSuccessResponse), а не массив this.items
Я не знаю другого кода, например, откуда взялся this.items
, почему вы публикуете обновленные элементы на onItemDeleted
. Но, вероятно, я бы: а) передал this.items
в метод удаления, также как и delete(id, items)
, потому что в то время, когда придет ответ, вы не знаете, что произойдет с this.items
; б) эту вещь на карте переместите в отдельную функцию, которой будет removeById(items, id)
; в) упростить pipe
. Нравится:
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),
);
}
тьфу ... это имеет смысл прямо сейчас ... Я должен был привязать функцию непосредственно к функции removebyid.
pipe
отлично подходит для выражения того, что вы хотите сделать, по возможности с одним лайнером, становится намного более читаемым :)
хе-хе да .. спасибо .. я так застрял в своей голове .. теперь он работает, даже как глобальная вспомогательная функция :)
Я не знаю другого кода, например, откуда взялся
this.items
, почему вы публикуете обновленные элементы наonItemDeleted
. Но, вероятно, я бы: а) передалthis.items
в методdelete
, также как иdelete(id, items)
, потому что в то время, когда придет ответ, вы не знаете, что произойдет сthis.items
; б) то, что находится внутриmap
, переместите в отдельную функцию, это будетremoveById(items, id)
; c)pipe
станетswitchMap(checkServerSuccessResponse), map(removeById), tap(onItemDeleted.next), catchError(returnFalse)
(сокращенные вызовы соответствуют этому комментарию).