0
votes

I'm trying to make a series of XHR GETs based on results of an initial request. I have an array of observables of the secondary requests I want to make, and I can use Array.map to iterate over them and subscribe in sequence to log all of their returned values, but I cannot understand how to format them into a flattened observable that I can print to the screen using the async pipe's single subscription:

ngOnInit() {
  // initial request - returns data on a planet
  this.planet$ = this.starWarsService.getEntityById("planets", "1");
  this.residentData$ = this.planet$.pipe(
    map(planets =>
      planets.residents.map(planet =>
        // get character data for each resident, `split` just grabs the index to construct the URL
        this.starWarsService.getEntityById("people", planet.split("/")[5])
      )
    ),
    tap(results => {
      results.map(result => {
        result.subscribe(data => {
          // this prints resident/character data correctly
          console.log("data", data);
        });
      });
    })
  );
}

How can I unwrap this array of observables into something I can unpack with a single async pipe?

StackBlitz

2

2 Answers

0
votes

you you want some like?

this.planet$=this.starWarsService.getEntityById("planets", "1").pipe(
  share()) //<--pipe(share()) is for only one call
this.residentData$ = this.planet$.pipe( 
  switchMap((planet:any)=>{
     //with each resident create an observable and use forkJoin
    return forkJoin(planet.residents.map(x=>
         this.starWarsService.getEntityById("people",x.split("/")[5])))
  }))
0
votes

Sounds like you want to zip your observables, then flatMap them. The result will be an Observable, where T is the return type of your single observables.

Like this:

this.residentData$ = this.planet$.pipe(
  flatMap(planets => zip(...planets.residents.map(planet =>
      this.starWarsService.getEntityById("people", planet.split("/")[5])))
  ),
  tap(result => {
    console.log('result', result);
  }),
);