0

I have an input of a string array for Enums I want to recieve from server:

enumList = ['somethin','branch','country', 'serviceType', 'thatandthis'];

I then have a generic http-service method that takes an enumList string as a parameter and returns an HttpClient observable for that Enum service:

this.webApi.getEnumByName('somethin','en').subscribe((res)=>{/*do something*/})
this.webApi.getEnumByName('branch','en').subscribe((res)=>{/*do something*/})...

I'm than combining the two into a loop

   for (const item of this.enumList) {
      this.webApi.getEnumByName(item).subscribe((res: any) => {
          this.enums[item] = res;
      });
    } 

But this is not good... I want the a subscription that completes only once when all subscriptions has resolved, while keeping a reference to the associated item string

using an array of observables returned from this.webApi.getEnumByName(item), concat or forkJoin won't work because they won't keep refference to the associated string/key/token of the response e.g the string in the enumList.

The end result of these concatinated observables should be:

{
    'somethin':{respopnse...},
    'branch':{respopnse...},
    'country':{respopnse...},
    'serviceType':{respopnse...},
    'thatandthis':{respopnse...}
}

breaking my head on this will appriciate an rxjs solution

Tomas Katz
  • 1,653
  • 1
  • 13
  • 27

3 Answers3

0

You can create a function to pass in this.enumList and still getting the same reference

function getResponse(enum){
  return forkJoin(....).subscribe(....)
}

or

forkjoin this.enumList with http call list

forkJoin(of(this.enumList), forkJoion(httpcall1,htttpcall2))
.subscribe([enum,responsesArray]=>....)
Fan Cheung
  • 10,745
  • 3
  • 17
  • 39
0

If I understand right your problem, you may want to consider something like this.

First of all you build an Observable with a function like this

function obsFromItem(item) {
   return this.webApi.getEnumByName(item).pipe(
      tap(res => this.enums[item] = res),
   )
}

The above logic says that as soon as getEnumByName notifies its result, than the result is set into this.enums at the right item.

Now that you have a similar function, you can create an array of Observables to be passed into forkJoin like this

arrayOfObs = enumList.map(item => obsFromItem(item))
forkJoin(arrayOfObs).subscribe()

When forkJoin(arrayOfObs) notifies, it means that all the Observables built via obsFromItem have emitted and therefore this.enums should be rightly filled.

forkJoin gives you parallel execution. If you substitute forkJoin with concat you get sequential execution.

In this article you may find some typical patterns of use of Obaservables with http calls.

Picci
  • 16,775
  • 13
  • 70
  • 113
0

You can combine several observables together like that:

forkJoin(enumList.reduce<any>((result, key) => {
  result[key] = this.webApi.getEnumByName(key,'en');
  return result;
}, {})).subscribe(allTogether => {
  // allTogether.somethin;
  // allTogether.branch;
  // ...
});
satanTime
  • 12,631
  • 1
  • 25
  • 73