user2950017 user2950017 - 3 months ago 49
AngularJS Question

using toFixed() in Angular is not working

I am having two issue in this page
https://plnkr.co/edit/c7r4CAR1WJrOzQUybip2?p=preview


  1. When the USD amount is 3, it gives 2.219999 value in EUR. I have tried using
    .toFixed(2)
    but it's not working.

  2. Another problem is I am calling
    ng-model="curr.to()"
    . Even though it outputs the result correctly, there is a console error.

    angular.js:13920 Error: [ngModel:nonassign] Expression 'curr.to()' is non-assignable. Element: <input type="number" ng-model="curr.to()" class="ng-pristine ng-untouched ng-valid">



Any help would be appreciated.

Answer

1. You probably got an error, because toFixed converts the number to a string, and you can't bind it to your input. A simple Number(watever.toFixed()) would do.

2. You can't bind a function expression to ngModel since it performs two-way data binding. You can alternatively use watch instead.

Note: I am personally against your 1st method. The controller should not care how the data be displayed on the view. You should consider another approach by using filter, etc..

However, here's a sample of your working version.

(function(angular) {
  'use strict';

  angular.module('finance', []);
  angular.module('finance').factory('currencyConverter', function() {
    var currencies = ['USD', 'EUR', 'CNY'];
    var usdToForeignRates = {
      USD: 1,
      EUR: 0.74,
      CNY: 6.09
    };

    var convert = function(amount, inCurr, outCurr) {
      var res = amount * usdToForeignRates[outCurr] / usdToForeignRates[inCurr]
      return Number(res.toFixed(2));
    };

    return {
      currencies: currencies,
      convert: convert
    }
  });

  angular.module('currencyConvert', ['finance']);
  angular.module('currencyConvert').controller('currencyCnvtCtrl', ['$scope', 'currencyConverter',
    function InvoiceController($scope, currencyConverter) {
      this.from = 1;
      this.inCurr = 'USD';
      this.outCurr = 'CNY';
      this.currencies = currencyConverter.currencies;

      this.to = 0;

      var w1 = $scope.$watch('curr.from', function() {
        $scope.curr.to = currencyConverter.convert($scope.curr.from, $scope.curr.inCurr, $scope.curr.outCurr);
      });
      var w2 = $scope.$watch('curr.inCurr', function() {
        $scope.curr.to = currencyConverter.convert($scope.curr.from, $scope.curr.inCurr, $scope.curr.outCurr);
      });
      var w3 = $scope.$watch('curr.outCurr', function() {
        $scope.curr.to = currencyConverter.convert($scope.curr.from, $scope.curr.inCurr, $scope.curr.outCurr);
      });
      var w4 = $scope.$watch('curr.to', function() {
        $scope.curr.from = currencyConverter.convert($scope.curr.to, $scope.curr.outCurr, $scope.curr.inCurr);
      });

      $scope.$on('$destroy', function() {
        w1();
        w2();
        w3();
        w4();
      });

    }
  ]);

})(window.angular);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="currencyConvert">
  <h1>Currency Converter</h1>
  <section class="currency-converter" ng-controller="currencyCnvtCtrl as curr">
    <h4>Type in amount and select currency</h4>
    <input type="number" ng-model="curr.from">

    <select ng-model="curr.inCurr">
      <option ng-repeat="c in curr.currencies">{{c}}</option>
    </select>

    <br>
    <input type="number" ng-model="curr.to">

    <select ng-model="curr.outCurr">
      <option ng-repeat='c in curr.currencies'>{{c}}</option>
    </select>
  </section>
</div>