Rob DePietro
Rob DePietro

Reputation: 324

Angular RXJS http for loop get call and merge results into one array

This may be a simple join but I am having issues getting this to work correctly. I will show the current code I'm working with. Although I've made a lot of changes with no good result.

I am looking to get the 'ID(s)' from the results of an Http get call and then using those ID(s) in another Http get call using a for loop and saving the results in one array....

The idea is to get the results from each for loop and store the results into one array.....hopefully that makes sense, thanks.

component.ts

array1: any[];
entryResult: any[];
Id:any;

 ngOnInit() {

this.xService.getAll()
  .subscribe(entryResult=> {
    this.entryResult= entryResult;

  for (let i of this.entryResult) {
  this.Id = i.id;
  this.array1.push(this.xService.getStuff(this.Id))
  forkJoin(this.array1).subscribe((res => {
   console.log(res);
 }))
  }
})

Upvotes: 3

Views: 1170

Answers (2)

shenghua lian
shenghua lian

Reputation: 149

Avoid subscribe in a subscribe. This is just call back hell. Try using high order operators to combine different streams.

const getStuffList = (items) => forkJoin(
  items.map(item => this.xService.getStuff(item.id)),
);

this.xService.getAll().pipe(
  switchMap(results => getStuffList(results)),
).subscribe();

Upvotes: 1

Mrk Sef
Mrk Sef

Reputation: 8022

The RxJS way to do this is to transform your data in a pipe.

First we turn your array of entryResult into an array of xService.getStuff calls. These service calls need to be subscribed to. You can (as you've noted) use forkJoin to do that. We subscribe to the forkJoin with any of the flattening operators (mergeMap, switchMap, concatMap -> I picked switchMap here).

Then log the results. That looks liek this:

this.xService.getAll().pipe(
  map(entryResult => entryResult.map(i => 
    this.xService.getStuff(i.id)
  )),
  switchMap(getStuffArray => forkJoin(getStuffArray))
).subscribe(console.log);

You can combine the map and switchMap into one switchMap operator as follows:

this.xService.getAll().pipe(
  switchMap(entryResult => forkJoin(
    entryResult.map(i => 
      this.xService.getStuff(i.id)
    ))
  )
).subscribe(console.log);

And if you need your global values set. (???????!)

this.xService.getAll().pipe(
  tap(entryResult => this.entryResult = entryResult),
  map(entryResult => forkJoin(
    entryResult.map(i => {
      this.Id = i.id;
      return this.xService.getStuff(i.id)
    }))
  )
).subscribe(console.log);

Upvotes: 3

Related Questions