在forEach循环中调用Angular服务

时间:2019-05-12 13:55:38

标签: angular rxjs

我是Angular 4的初学者。 我想以EUR货币计算总发票, 我有价格值和每个价格的货币类型。当我想计算总金额时,我需要调用exchangeService service以获得货币汇率。

当我检查invoicesSumTotalValue的值时,它为0。 这是我的代码:

    calcInvTotalValue(){

     let prods = (<FormArray>(<FormGroup>(<FormArray>this.productData.parent.parent).parent).controls['products']);
        let invoicesSumTotalValue = 0;


        prods.controls.forEach(c => {
          let price = (<FormGroup>(<FormGroup>c).controls['selected_products']).controls['price'].value;
          let currency = (<FormGroup>(<FormGroup>c).controls['selected_products']).controls['currency'].value;

          this.exchangeService.getExchRate(currency, "USD").subscribe(
            vl => {
              let exRate = vl;
              invoicesSumTotalValue = invoicesSumTotalValue + (parseFloat(price) * exRate);
            },
            (error: any) => console.log(error)
          );
        });
        console.log("iNVOICE total is: " + invoicesSumTotalValue);

如何为prods数组的每个值调用service? 谢谢!

2 个答案:

答案 0 :(得分:1)

您应使用RxJS的forkJoin等待Array.forEach()循环完成,然后返回所有可观察对象。如果您熟悉JavaScript中Promises的用法,它实际上类似于Promise.all

计算invoicesSumTotalValue时会遇到问题,因为返回可观察值是一个异步操作,因此forEach循环的下一次迭代可能会在返回getExchRate()的响应之前执行

这是我建议对您的代码进行的修改。基本上,forkJoin()循环的所有迭代完成后,我们将使用forEach()返回可观察值。从那里开始,在返回观测值的subscribe()块中,我们处理invoicesSumTotalValue的计算。

const prods = (<FormArray>(<FormGroup>(<FormArray>this.productData.parent.parent).parent).controls['products']);
const observablesList = [];

prods.controls.forEach(c => {
  const currency = (<FormGroup>(<FormGroup>c).controls['selected_products']).controls['currency'].value;
   observablesList.push(this.exchangeService.getExchRate(currency, 'USD'));
})

forkJoin(observablesList).subscribe(response => {
  //console.log(response);
  // handle the rest
});

答案 1 :(得分:0)

您正在尝试同步记录一个异步值“ invoicesSumTotalValue”,这就是这里的问题。

将方法级别的变量invoicesSumTotalValue移到类级别,并在HTML模板中打印该值,您将获得实际的总值。

由于http服务返回的价格值是可观察的,因此您在进行console.log时不会立即可用。

按如下所示修改代码,它将可以正常工作:(为了方便起见,我模拟了prod数组以在此处显示结果)

组件代码:

导出类ExchangeComponent实现OnInit {

invoicesSumTotalValue = 0;

constructor(private exchangeService: ExchangeService) { }

ngOnInit() {
    this.calcInvTotalValue();
}

calcInvTotalValue() {

    let prods = [
        {
            price: 10,
            currency: 'INR'
        },
        {
            price: 20,
            currency: 'EUR'
        }
    ];

    prods.forEach(c => {
        let price = c['price'];
        let currency = c['currency'];

        this.exchangeService.getExchangeRate("USD", currency).subscribe(
            vl => {
                let exRate = vl['rates'][currency];
                this.invoicesSumTotalValue = this.invoicesSumTotalValue + (parseFloat(String(price)) * parseFloat(exRate));
            },
            (error: any) => console.log(error)
        );
    });
}

}

模板代码:

    {{invoicesSumTotalValue}}