我有一个交易数据集,我想用额外的数据,如给定日期的汇率,并将其直接发回我的api。但是我只是在没有任何修改的情况下得到我的原始交易,而且我还是Angular和Rxjs的新手。所以我可以对运营商使用一些帮助。
我有一个按钮,从一个函数调用几个apis:
// component.ts
public click() {
this.deposits = this.depositApi.getAllDeposits()
.subscribe(
result => {
result.map(x => this.depositApi.enrichAndSaveDeposit(x));
}
);
}
获取当地api的所有原始交易,这些交易都有日期。 (这个有效)
// depositApiService
public getAllDeposits(): Observable<DepositModel[]> {
return this.http.get<DepositModel[]>(AppConfig.localJsonServerUrl + AppConfig.api.deposits)
.pipe(
catchError(this.handleError('getAllDeposits', null))
);
}
在这里,我调用外部API来获取给定日期的汇率,然后进行一些计算并将其发回给本地API。
但它永远不会进入mergeMap部分。
// depositApiService
public enrichAndSaveDeposit(deposit: DepositModel): Observable<DepositModel> {
return this.apiService.getHistoricEurRate(deposit.date)
.pipe(
mergeMap(data => {
deposit.historicExchangeRate = data.rates.USD;
deposit.exchangeRate = deposit.sellAmount / deposit.buyAmount;
deposit.sellAmountInUsd = deposit.sellAmount * data.rates.USD;
deposit.exchangeRateInUsd = deposit.exchangeRate * data.rates.USD;
return this.saveLocalDeposit(deposit);
}), catchError(this.handleError('enrichAndSaveLocalDeposit', deposit))
);
}
这里调用外部api(这是有效的)。
// apiService
public getRemoteExchangeRates(): Observable<ExchangeRateModel> {
return this.http.get<ExchangeRateModel>(AppConfig.exchangeRateApi + '/latest')
.pipe(
catchError(this.handleError('getRemoteExchangeRates', null))
);
}
这是本地api的帖子。 (永远不要到达这一点)
// depositApiService
private saveLocalDeposit(deposit: DepositModel): Observable<DepositModel> {
return this.http.post<DepositModel>
(
AppConfig.localJsonServerUrl + AppConfig.api.deposits,
deposit,
{ headers: new HttpHeaders().set('Accept', 'application/json') }
)
.pipe(
catchError(this.handleError('saveLocalDeposit', deposit))
);
}
这是我给出的类似问题的答案,概述了如何进行这个how to build single object from 2 http requests in angular, without adding another value
另外,我想向您提供一个关于RxJS的提示,我认为这是目前问题的一部分。让我们看看你的代码,如下所示。
public click() {
this.deposits = this.depositApi.getAllDeposits()
.subscribe(
result => {
result.map(x => this.depositApi.enrichAndSaveDeposit(x));
}
);
}
此代码订阅Observable getAllDeposits,然后说当返回值时,使用enrichAndSaveDeposit映射该值。但是,您的enrichAndSaveDeposit代码也是一个Observable,因此如上所述,永远不会被调用,因为它永远不会被订阅。下面我写了一些可以修复这个特定情况的东西。
public click() {
this.deposits = this.depositApi.getAllDeposits()
.subscribe(
result => {
result.map(x => {
this.depositApi.enrichAndSaveDeposit(x)
.subscribe( // this is the subscribe that is needed to make the second part of the chain work
enrichedResult => {
// do something with the enrichedResult here
}
);
};
}
);
}
希望这可以帮助。
问题是你永远不会订阅从enrichAndSaveDeposit
返回的Observable,因此永远不会发出http POST。
订购然后提供观察员功能,即使是空的,也足够了。
public click() {
this.deposits = this.depositApi.getAllDeposits()
.subscribe(
result => {
result.map(x => this.depositApi.enrichAndSaveDeposit(x).subscribe(() => {}));
}
);
}
Angular的HttpClient的方法(get,post,...等)返回冷Observables,这意味着它们只在订阅时开始运行。这有两个重要原因:
阅读以下内容将有助于您了解冷热Observables之间的区别:
https://blog.thoughtram.io/angular/2016/06/16/cold-vs-hot-observables.html https://medium.com/@benlesh/hot-vs-cold-observables-f8094ed53339