В основном я пытаюсь опросить данные с 2 конечных точек для сбора участников гонки. У меня есть 2 метода в моем сервисе, которые делают запросы API, используя угловой http-клиент, и возвращают Observables. Первый метод принимает массив идентификаторов и возвращает массив основных данных участника (имя, прошедшее время, текущая контрольная точка) для каждого переданного идентификатора, а второй метод принимает один идентификатор и возвращает массив результатов из каждой контрольной точки. для этого участника
У меня есть наблюдаемая, которая является результатом первого вызова службы. Затем я передаю и отображаю это так, чтобы я мог работать с массивом, а затем делаю стандартную карту массива javascript для итерации элементов. Бит, на котором я действительно застрял, - для каждого «участника» в массиве, который соответствует условию, мне нужно сделать еще один http-вызов ко второй конечной точке и присвоить значение этого результата, наблюдаемого, свойству участника. В идеале исходная Observable должна возвращаться, как только она станет доступной, и тогда каждый участник в этом результирующем массиве будет обновлять результаты контрольной точки по завершении вызовов API.
Я только начинаю изучать rxjs, angular и ngrx, и я все еще борюсь с наблюдаемыми потоками, однако у меня есть эффект ngrx, который выглядит следующим образом
@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).pipe(
map((participants: Participants[]) => {
return participants.map(participant => {
if (expandedDetailIds.includes(participant.id)) {
this.apiService.getParticipantDetailResults(participant.id).pipe(
map((results: ParticipantResults[]) => {
return (participant.results = results);
})
);
}
return participant;
});
}),
map(updates => {
debugger;
return 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 }))
)
);