Как запустить наблюдаемое зависит от результата предыдущего наблюдения с Rx JS в Angular? - PullRequest
0 голосов
/ 26 марта 2020

Мне нужно сделать следующее:

  • удалить элемент с удаленного сервера
  • , если он успешен, удалить элемент из локального хранилища
  • , если он успешен, перезагрузите элементы с удаленного сервера

Теперь у меня есть этот код, но он не работает должным образом, потому что третий шаг не выполняется.

delete(model: T, paginate: PaginateInterface): Observable<any> {
  return this.remoteStorageService.delete(model).pipe(map((resultDelete: boolean) => {
    if (resultDelete) {
      this.localStorageService.delete(model);
      return this.remoteStorageService.getAll().pipe(map( (resultGetAll: PaginateInterface) => {
        return resultGetAll;
      }));
    }

    return paginate;
  }));
}

Я пытался использовать Rx JS функция switchMap, но я полностью потерян.

Как запустить функцию, зависит от результата наблюдаемой, а затем другой наблюдаемой, что возвращает с результатами?

Ответы [ 2 ]

0 голосов
/ 26 марта 2020

Из кода, который вы разместили, и комментариев, я предполагаю, что remoteStorageService.delete и remoteStorageService.getAll() возвращают некоторые наблюдаемые, в то время как localStorageService.delete() возвращает void.

Если это так, вы можете попробовать что-то вроде этого

delete(model: T, paginate: PaginateInterface): Observable<any> {
  return this.remoteStorageService.delete(model)
  .pipe(
     concatMap((resultDelete: boolean) => {
        if (resultDelete) {
           this.localStorageService.delete(model);
           return this.remoteStorageService.getAll();
        } else {
           return EMPTY  // if the delete fails you complete the Observable
           // you can also error here if you want to terminate the Observable with an error
        }
     })
  )
}

Ключевым моментом здесь является то, что сначала вы выполняете remoteStorageService.delete и ждете, пока наблюдаемое не сообщит о своем результате. Использование оператора concatMap гарантирует, что Наблюдаемые, содержащиеся в concatMap, будут выполнены (или точнее подписаны) только после того, как remoteStorageService.delete уведомит о своем результате. Затем вы можете использовать результат remoteStorageService.delete, чтобы решить, следует ли возвращать remoteStorageService.getAll() или возвращать EMPTY.

. В первом случае remoteStorageService.getAll() будет Наблюдением, подписанным Компонентом, во втором case EMPTY будет Observable, подписанным Компонентом. EMPY - это наблюдаемая, которая ничего не излучает и немедленно прекращает работу.

0 голосов
/ 26 марта 2020

Я предполагаю, что шаги 1 и 3 - это работа компонента, а шаг 2 - работа службы.

Вы можете использовать метод tap, чтобы сделать дополнительные логи c при успехе или неудаче наблюдаемой:

Служба:

deleteItem(model): Observable<any> {
  return this.http.delete<any>(`${yourUrl}`, model)
    .pipe(
      tap(result => {
        // success
        // delete from local storage here
      }, error => {
        // fail
        // in case you need logic for failure, put it here
      })
    );
}

Компонент:

delete(model) {
  this.yourService.deleteItem(model)
    .subscribe(result => {
      // success, local storage is updated at this point
      // reload your data
    }, error => {
      // fail, local storage was not updated
      // do your error handling logic here
    });
}

Если необходимо выполнить шаг 2 в компоненте, просто переместите код pipe в свой компонент.

...