0

There are quite a few questions of similar nature, I think this is a bit different.

Consider the following code:

arr = [];

this.service1.getItem()
  .subscribe(item => {
    Object.entries(item).forEach(([key, value]) => {
    if (some_condition_true) {
      this.service2.getSomeItems2(value.prop1).pipe(first())
        .subscribe(result => value.xyz = result);
        this.arr.push(value);
    }
 });

});

// This line should execute only after the 'forEach' above completes
this.someService.someMethod(arr);

The issue is I do not know in advance how many times service2.getSomeItems2 will be called.

Also, zip and forkJoin take Observables but I have subscribed already. Maybe I can tap instead of subscribe'ing. But the fact remains about unknown number of Observables.

kmansoor
  • 4,265
  • 9
  • 52
  • 95
  • See this: https://stackoverflow.com/questions/42334469/observable-forkjoin-with-a-for-loop. Just insert that *before* your subscribe. (But consider putting the `forkJoin` code in a service and the `subscribe` in the component.) – DeborahK Jan 25 '19 at 19:10
  • You could use `.subscribe({ complete: () => this.someService.someMethod(arr); })` for the nested subscription but I'd rather recommend restructuring it so you won't have nested `subscribe` calls at all with `mergeMap` or `concatMap` for example. – martin Jan 25 '19 at 20:27

1 Answers1

0

How about this?

this.service1.getItem()
  .pipe(switchMap(items => {
      const itemReqs = Object.entries(items)
                       .filter(v => some_condition_true_or_false)
                       .map(item => this.service2.getSomeItems2(item.prop1).pipe(first()));

     return forkJoin(itemReqs);

  }))
  .subscribe(data_from_service_2_calls => {
     data_from_service_2_calls.forEach(v => console.log(v))
   });

There might be syntax mistakes but I think this is what you want. Remember you should avoid subscribe inside subscribe.

Hope that helps!

kashpatel
  • 696
  • 1
  • 6
  • 18