rtn
rtn

Reputation: 2034

How to chain multiple .map() calls on previous items using rxjs

In the example below I was wondering how you would go about preforming two operations on the same response from the .swichMap().

In the example I put the second .map in which is clearly wrong but sort of illiterates what I want to do. How would I go about calling two functions. Also when I break the fist map() out into a function like .map(response => {fn1; fn2;}); typescript throws an error?

@Effect()
    getUserCourse$: Observable<Action> = this.actions$
        .ofType(userCourse.ActionTypes.LOAD_USER_COURSE)
        .map<string>(action => action.payload)
        .switchMap(userCourseId => this.userCourseApi.getUserCourse(userCourseId))
        .map(response => new userCourse.LoadUserCourseSuccessAction(response.data));
        .map(response => new course.LoadCourseSuccessAction(response.course));

Upvotes: 2

Views: 9418

Answers (1)

dotcs
dotcs

Reputation: 2296

For this answer I'm assuming that both functions userCourse.LoadUserCourseSuccessAction and course.LoadCourseSuccessAction do return Observables. If not you can always create one with Rx.Observable.of or Rx.Observable.fromPromise in case of for example an AJAX call.

If I understand you correctly you want to do independent things with the response, but do them in parallel and merge the results back in the stream. Have a look at the following code that shows how this can be archived.

Rx.Observable.of(
  {data: 'Some data', course: 'course1'},
  {data: 'Some more data', course: 'course2'}
).mergeMap((obj) => {
  // These two streams are examples for async streams that require
  // some time to complete. They can be replaced by an async AJAX 
  // call to the backend.
  const data$ = Rx.Observable.timer(1000).map(() => obj.data);
  const course$ = Rx.Observable.timer(2000).map(() => obj.course);

  // This Observable emits a value as soon as both other Observables
  // have their value which is in this example after 2 seconds.
  return Rx.Observable.combineLatest(data$, course$, (data, course) => {
    // Combine the data and add an additinal `merged` property for
    // demo purposes.
    return { data, course, merged: true };
  });
})
.subscribe(x => console.log(x));

Runnable demo

Upvotes: 2

Related Questions