0

I am a bit confused with rxjs operators. I have few api calls that return observable:

getCurrentUser(): Observable<any> {
    return this.http.get<any>(userUrl);
  }

tagsList(): Observable<string[]> {
    return this.http.get<string[]>(tagsUrl);
  }

timezonesList(): Observable<Timezone[]> {
    return this.http.get<Timezone[]>(timezonesUrl);
  }

I want to call getCurrentUser() then with result of returning value call action LoadUser(user) Then after user loads call multiple async requests at the same time:

tagsList(), timezonesList()

And then with results of returning value of them call actions LoadTags(tags), LoadTimezones(timezones)

So it should looks like something like this:

init() {
  this.accountsApi.getCurrentUser()
      .map((user: User) => this.store.dispatch(new LoadUser({ user })))
      .map(
        this.commonApi.tagsList(),
        this.commonApi.timezonesList(),
        this.commonApi.authoriztionServicesList()
      )
      .map((tags, timezones, authorizationServices) => {
        this.store.dispatch(new tagsActions.LoadTags(tags));
        this.store.dispatch(new timezonesActions.LoadTimezones(timezones));
        this.store.dispatch(new authorizationServicesActions.LoadAuthorizationServices(authorizationServices));
      });
}

I know that this operators are wrong. What operators should i use for this? I have already done it with promises, but i am sure that i can do it with rxjs operators in less line of code.

P.S. Also it is interesting for me how i can do this with async / await? Thank you

mr__brainwash
  • 1,334
  • 3
  • 16
  • 40

1 Answers1

0

In your original code you are using map a bit too much, for some use cases you may not need to map.

init() {
  return this.accountsApi.getCurrentUser()
      .do((user: User) => this.store.dispatch(new LoadUser({ user })))
      .forkJoin(
        this.commonApi.tagsList(),
        this.commonApi.timezonesList(),
        this.commonApi.authoriztionServicesList()
      )
      .do((results) => {
        this.store.dispatch(new tagsActions.LoadTags(results[0]));
        this.store.dispatch(new timezonesActions.LoadTimezones(results[1]));
        this.store.dispatch(new authorizationServicesActions.LoadAuthorizationServices(results[2]));
      });
}

forkJoin lets you fire off many observable subscriptions and once all subscriptions produce values you get a single array of observable values back.

The do operator introduces side effects to launch your store actions since you don't want to create any arrays.

Mike Tung
  • 4,735
  • 1
  • 17
  • 24
  • Thanks you, i know about too much maps, i wrote it is just as an example, because i don't know what operators should i use there. But is it possible to make it without array[index]? Handle it somehow with interfaces of returning values of commonApi's calls? Like i wrote in my last code example – mr__brainwash May 15 '18 at 15:04