У меня проблема при получении результатов двух асинхронных вызовов http.
Первый маршрут называется /contracts, а второй - /shipments.
Каждый контракт связан с поставкой, поэтому он имеет свойство shipmentId.
Я хочу получить все контракты и для каждого контракта получить его соответствующую отправку с моего сервера REST.
Я попытался вызвать как getContracts(), так и getShipments(), а затем контракт forEach, чтобы использовать find в моем shipments[] (результат метода getShipments()), но иногда ответ на вызов отгрузки возвращается после ответа на вызов контракта, и поэтому возвращается ошибка cannot read property x of undefined.
Я пробовал использовать также getShipmentById(), но это не дает мне уверенности в том, что все время посылка будет возвращена после заключения контракта.
Как этого добиться с помощью Angular / RxJS?
Вот соответствующие части моего кода:
getContracts(): Observable<Contract[]> {
return this.http.get<Contract[]>(this.contractsUrl)
.pipe(
retry(3),
catchError(this.handleError('getContracts', []))
);
}
getShipments(): Observable<Shipment[]> {
return this.http.get<Shipment[]>(this.shipmentsUrl)
.pipe(
retry(3),
catchError(this.handleError('getShipments', []))
);
}
getShipmentById(id: string): Observable<Shipment | {}> {
return this.http.get<Shipment>(`${this.shipmentsUrl}/${id}`)
.pipe(
retry(3),
catchError(this.handleError('getShipmentById'))
);
}
Возвращает ли конечная точка /contracts идентификатор или значение, которое необходимо использовать в /shipments? Или вы имеете в виду, что /contracts и /shipments вызываются одновременно, а затем следующий вызов происходит к /shipments/:id после завершения предыдущих? Вы можете захотеть создать Stackblitz и использовать of или что-то подобное, чтобы продемонстрировать структуры потока и возврата данных.





forkJoin сделал свое дело.
Спасибо за ответ, я не знал об этой функции. Я публикую здесь код, возможно, он поможет кому-то еще, у кого есть эта проблема:
getContracts(): void {
forkJoin(
this.contractService.getContracts(),
this.shipmentService.getShipments()
)
.subscribe(([contracts, shipments]) => {
if (Array.isArray(contracts) && Array.isArray(shipments)) {
this.contracts = contracts
.map(contract => {
contract.shipment = shipments.find(shipment => shipment.shipmentId === contract.shipmentId);
return contract;
});
}
console.info(contracts);
});
}