2017-09-28 4 views
0

J'effectue un premier appel à gitlab Api qui renvoie tous les projets étoilés. Une fois terminé, je souhaite récupérer tous les jalons associés à chaque projet afin de les ajouter à un objet de projet personnalisé, puis de les stocker quelque part.rxjs angular - fractionne le retour d'un observable avec résultat foreach et merge

Y at-il un opérateur rxjs qui me permet de faire un appel HTTP forEach et d'attendre que tous les appels se terminent et fusionnent le résultat en un?

getStarredProjects$(): Observable<GitlabProject[]> { 
    return this.http.get(this.starredProjectsUrl).map((res: GitlabProject[]) => { 
     res.forEach((project:GitlabProject)=>{ 
      this.getMileStones(project.id).subscribe() 
     }) 
     return res 
    }) 
} 

getMileStones(projectId:number){ 
    return this.http.get(`${this.projectUrl}/${projectId}/milestones`) 
} 

Répondre

1

Vous pouvez créer un tableau des observables auxquels vous souhaitez vous abonner, puis les exécuter simultanément. forkJoin() émettra lorsque toutes les observables seront terminées.

getStarredProjects$(): Observable<ProjectMilestones[]> { 
    return this.http.get(this.starredProjectsUrl) 
     .flatMap((res: GitlabProject[]) => { 
      // build out array of observables 
      let observables$ = res.map(project => { 
       return this.getMileStones(project.id); 
      }); 
      // return array of observables to run simultaneously 
      // spread operator here is optional, forkJoin() would also accept an array of observables 
      return Observable.forkJoin(...observables$); 
     }) 
} 

getMileStones(projectId:number){ 
    return this.http.get(`${this.projectUrl}/${projectId}/milestones`) 
} 

this.getStarredProjects$.subscriber(res => { 
    // res is an array of the results. (ie. res[0] is the result of the first observable in the observables$ array, res[1]...res[x]) 
}); 

Docs sur forkJoin - https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/forkjoin.md

J'utilise aussi flatMap ici pour chaîner l'appel api initial et les appels subséquents api. Editer - Comme le montre le cartable, forkJoin excepte un tableau d'observables ou un observable pour chaque paramètre. Il peut être avantageux d'utiliser l'opérateur de propagation dans ce cas pour être cohérent avec certains des autres opérateurs de combinaison (comme la concat), où vous ne pouvez pas passer un tableau d'observables.

+1

'forkJoin' acceptera un seul paramètre qui est [un tableau des observables] (https://github.com/ReactiveX/rxjs/blob/5.4.3/src/observable/ForkJoinObservable.ts#L34-L37). Cependant, comme vous, je préfère utiliser la syntaxe spread, car elle est cohérente entre les opérateurs. Par exemple. vous ne pouvez pas passer un tableau d'observables 'concat', car il serait traité comme un' ObservableInput'. – cartant

+0

@cartant c'est un bon point. J'ai mis à jour ma réponse pour refléter cela. – LLai