Позвоните в сервис Angular внутри цикла forEach - PullRequest
0 голосов
/ 12 мая 2019

Я новичок в Angular 4. Я хочу рассчитать общую сумму счета в евро, у меня есть значение цены и тип валюты для каждой цены.Когда я хочу рассчитать общую сумму, мне нужно позвонить в службу exchangeService, чтобы узнать обменный курс валюты.

Когда я проверяю значение 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?Спасибо!

Ответы [ 2 ]

1 голос
/ 12 мая 2019

Вы должны использовать forkJoin RxJS, чтобы дождаться завершения цикла Array.forEach(), прежде чем возвращать все наблюдаемые. Если вы знакомы с использованием Promises в JavaScript, на самом деле это похоже на 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
});
0 голосов
/ 12 мая 2019

Вы пытаетесь синхронно унаследовать асинхронное значение 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}}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...