Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/apache-flex/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
rxjs可观测<;数组<;T>;,如何为每个数组项进行http服务调用,并将该可观察结果分配给属性?_Rxjs_Observable_Angular Httpclient - Fatal编程技术网

rxjs可观测<;数组<;T>;,如何为每个数组项进行http服务调用,并将该可观察结果分配给属性?

rxjs可观测<;数组<;T>;,如何为每个数组项进行http服务调用,并将该可观察结果分配给属性?,rxjs,observable,angular-httpclient,Rxjs,Observable,Angular Httpclient,基本上,我正在尝试从两个端点为一个竞赛参与者的集合轮询数据。我的服务中有两个方法,它们使用AngularHTTP客户端发出api请求,并返回可观测值。第一个方法获取一个Id数组,并为传递的每个Id返回一个基本参与者数据数组(名称、经过的时间、当前检查点),第二个方法获取一个Id,并从该参与者的每个检查点返回一个结果数组 我有一个可观察的结果,这是第一次服务调用的结果。然后,我对其进行管道和映射,以便使用数组,然后执行标准javascript数组映射来迭代元素。我真正感兴趣的是,对于数组中匹配条件

基本上,我正在尝试从两个端点为一个竞赛参与者的集合轮询数据。我的服务中有两个方法,它们使用AngularHTTP客户端发出api请求,并返回可观测值。第一个方法获取一个Id数组,并为传递的每个Id返回一个基本参与者数据数组(名称、经过的时间、当前检查点),第二个方法获取一个Id,并从该参与者的每个检查点返回一个结果数组

我有一个可观察的结果,这是第一次服务调用的结果。然后,我对其进行管道和映射,以便使用数组,然后执行标准javascript数组映射来迭代元素。我真正感兴趣的是,对于数组中匹配条件的每个“参与者”,我需要对第二个端点进行进一步的http调用,并将生成的可观察值的值分配给参与者的属性。理想情况下,原始可观察对象将在可用时立即返回,然后在api调用完成时,结果数组中的每个参与者都将使用检查点结果进行更新

我只是刚刚开始学习rxjs,angular和ngrx,我仍然在为可观测流挣扎,但是我有一个ngrx效果,看起来像这样

@Effect()
pollDataForCollection$=此.CollectionEventActions$.pipe(
ofType(CollectionActions.onCountdownRestarted.type),
最晚从(
此.featuresStore$.select(collectionSelectors.SelectAllFavorites),
此.featuresStore$.select(collectionSelectors.SelectedExpandedFavorites)
),
switchMap(([action,faves,ExpandedDetails])=>{
常量id:number[]=faves.map(fave=>fave.id);
返回此.apiService.getParticipantsById(ids).pipe(
地图((参与者:参与者[])=>{
返回参与者.map(参与者=>{
if(扩展的详细信息包括(参与者id)){
this.apiService.getParticipantDetailResults(participant.id).pipe(
map((结果:参与者结果[])=>{
返回(参与者。结果=结果);
})
);
}
返回参与者;
});
}),
地图(更新=>{
调试器;
返回CollectionActions.pollingDataSucceeded({items:updates});
}),
catchError(error=>of(CollectionActions.pollingDataErrored({error})))
);
})
);
这将成功地将参与者和项目的数组分配给每个参与者,但毫不奇怪,它不会将结果分配给参与者

更新以包括工作解决方案 非常感谢@user2216584提供的解决方案

  @Effect()
  pollDataForCollection$ = this.collectionEventsActions$.pipe(
    ofType(
      CollectionActions.onCountdownRestarted.type
    )
    , withLatestFrom(
      this.featuresStore$.select(collectionSelectors.selectAllFavourites)
    )
    , switchMap(([action, faves]) => {
      const ids: number[] = faves.map(fave => fave.id);
      return this.apiService.getParticipantsById(ids);
    })
    , withLatestFrom(
      this.featuresStore$.select(collectionSelectors.selectExpandedFavourites)
    )
    , switchMap(([participants, expandedFaves]) => {
      const favesWithDetailedResults = participants.map(participant => {
        if(expandedFaves.includes(participant.id)){
            return this.apiService.getParticipantCheckpointResults(participant.id).pipe(
              map((checkpointResults: ParticipantCheckpoint[]) => {
                const participantDetail: Participant = {
                  ...participant,
                  checkpoints: checkpointResults
                }
                return participantDetail;
              })
            )
        }else{
            return of(participant)
        }
      });

      return forkJoin(favesWithDetailedResults)
    })
    , map((updates) => {
      return CollectionActions.pollingDataSucceeded({ items: updates })
    })
    , catchError(error =>
      of(CollectionActions.pollingDataErrored({ error }))
    )
  );


这就是你需要做的- 对于每个参与者,您需要从details api收集可观察的内容,并将其推送到一个数组中。这个数组应该是一个可观察的集合。然后在
rxjs
forJoin
函数中使用此数组。请参阅下面的代码

- 

  @Effect()
  pollDataForCollection$ = this.collectionEventsActions$.pipe(
    ofType(
      CollectionActions.onCountdownRestarted.type
    )
    , withLatestFrom(
this.featuresStore$.select(collectionSelectors.selectAllFavourites)
,this.featuresStore$.select(collectionSelectors.selectExpandedFavourites)
    )
    , switchMap(([action, faves, expandedDetailIds]) => {
      const ids: number[] = faves.map(fave => fave.id);
      return this.apiService.getParticipantsById(ids);
),
switchMap(participants => {
 //for each participant map the detail api observable in an array
 const obs = participants.map(p => this.apiService.getParticipantDetailResults(participant.id));
return forkJoin(obs);
}),
map(joined => {
  // result from forkJoin will be an array of the api response in the order you added the observables. Also forkJoin only emit the value once for each of the observable it has the response; so it will wait for the response to comeback for the details for each participant 
 //now you can do whatever you want to do with this array
// may be parse it and send the success action to the store
})

非常感谢!我刚刚发现forkJoin一定是这个秘密拼图的一部分。我还必须有条件地执行第二个请求,并将第二个请求的结果映射到元素的属性。切换到分叉连接的地图是我错过的魔法。非常感谢!