简体   繁体   中英

RxJS Observable result from an Observable's output

I have an Angular 8 application, that uses two layers to store data: StorageService abstracts away the actual HTTP service calls, while it itself does not contain other methods than get and save of various data types.

Other services like BookmarkService use StorageService and implement the more complex business logic like adding a new bookmarked article.

The catch is, we might have to call StorageService twice, to load the data and then to save it.

I would like to expose potential errors to the caller site properly and I am wondering what the best solution would be to implement something like this, without introducing RxJS Subject objects at all. For example, is there any way to achieve this via merely piping? Can someone please give me an example on how to properly implement this pattern?

export class BookmarkService {

  constructor(private storageService: StorageService) {}

  addArticleToBookmarks(article: Article): Observable<SaveResponse> {

    this.storageService.getBookmarkedArticles().subscribe(articles =>

      articles.push(article);

      this.storageService.saveBookmarkedArticles(articles).subscribe(saveResponse => ...)

    });

    // want to return an Observable of saveResponse, if getBookmarkedArticles completed, 
    // or the error output of getBookmarkedArticles if it failed
    return ...

  }

Do you mean something like this ?

addArticleToBookmarks(article: Article): Observable<SaveResponse> {

  this.storageService.getBookmarkedArticles()
  .pipe(
    catchError(err => console.error(err))
    switchMap(articles => {
      articles.push(article);
      return this.storageService.saveBookmarkedArticles(articles);
    }
  ).subscribe(saveResponse => ...)

}

You can use a switchMap ormergeMap (also known as flatMap ) operator.

Here's a good explanation about the difference between both: https://javascript.tutorialhorizon.com/2017/03/29/switchmap-vs-flatmap-rxjs/

Example using switchMap :

    addArticleToBookmarks(article: Article): Observable<SaveResponse> {
        return this.storageService.getBookmarkedArticles().pipe(
            switchMap(articles => {
                articles.push(article);
                return this.storageService.saveBookmarkedArticles(articles)
            })
        );
    }

I have not tested it, but I'm quite sure, this will work

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM