How to properly chain rxjs 6 observables?

2019-04-14 14:46发布

Any suggestions, how this can be rewritten in more promise-chaining style?:

this.apiService.sendPutRequest('/api/users/activate', usrObj).pipe(
        map(() => {
            return this.apiService.sendGetRequest('/api/users/' + this.currentUserId).pipe(
                map(data => {
                    return this.setActiveUser(data).pipe(
                        map(() => {
                            return this.apiService.sendGetRequest('api/tasks/user/' + this.currentUserId).pipe(
                                map(tasks => {
                                    return this.taskService.setCurrentUserTasks(tasks);
                                })
                            );
                        })
                    );
                })
            );
        })
    );

3条回答
在下西门庆
2楼-- · 2019-04-14 15:32

use SwitchMap for that.

mainApiCall.pipe(
    switchMap(result=>secondApiCall(result)),
    switchMap(resultFromSecondApiCall=>thirdApiCall(resultFromSecond))
...
and so on
)
查看更多
可以哭但决不认输i
3楼-- · 2019-04-14 15:35

Use a single pipe for your problem. Just comma seperate different chainable operators like map, switchMap, mergeMap, tap, etc.

this.apiService.sendPutRequest('/api/users/activate', usrObj).pipe(
  switchMap((results) => this.apiService.sendGetRequest('/api/users/' + this.currentUserId)),
  tap((results) => this.setActiveUser(data)),
  switchMap(() => this.apiService.sendGetRequest('api/tasks/user/' + this.currentUserId)),
  tap((results) => this.taskService.setCurrentUserTasks(tasks))
);

Simplified: Use map if you just want to transform a value without any async api calls and pass it to another operator or a subscription, tap if you just want to catch values in between without transforming (e.g. for logging). And switchMap for dispatching additional api calls.

查看更多
闹够了就滚
4楼-- · 2019-04-14 15:47

You can use switchMap for handling observables and tap for side efects handling. And you need to subscribe because it's cold observable

For error handling use catchError for all requests

this.apiService.sendPutRequest('/api/users/activate', usrObj).pipe(
    catchError(err=> this.errorHandler(err)),
    switchMap(() => this.apiService.sendGetRequest('/api/users/' + this.currentUserId)
        .pipe(catchError(err=> this.errorHandler(err)))
    ),
    tap(data => this.setActiveUser(data)),
    switchMap(() => this.apiService.sendGetRequest('api/tasks/user/' + this.currentUserId)
        .pipe(catchError(err=> this.errorHandler(err)))
    ),
    tap(tasks => this.taskService.setCurrentUserTasks(tasks))
).subscribe()
查看更多
登录 后发表回答