Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to round in Javascript/Angular JS -- but remove insignificant digits

I have a the following statement in my Javascript controller:

$scope.myList = [0, 1, 0.5, 0.6666666];

My AngularJS template contains the following line:

<div ng-repeat="i in myList">{{i}}</div>

This produces the following HTML output:

<div>0</div>
<div>1</div>
<div>0.5</div>
<div>0.6666666</div>

I want the numbers to be rounded to 2 decimal places. However, I would like to see only significant digits in the output. I don't want to see trailing zeroes. How do I do it? Using {{i | number:2}} doesn't eliminate trailing zeroes.

like image 278
Saqib Ali Avatar asked Jan 08 '15 22:01

Saqib Ali


3 Answers

You could just multiple by 1 to convert it to true value.

<div ng-repeat="i in myList">{{(i | number:2)*1}}</div>

As noted from the comments above solution will break due to the locale formatting by angular number filter. If you need the locale formatting and rounding you could create an extension filter which underneath uses number filter and $locale service.

.filter('numberEx', ['numberFilter', '$locale',
  function(number, $locale) {

    var formats = $locale.NUMBER_FORMATS;
    return function(input, fractionSize) {
      //Get formatted value
      var formattedValue = number(input, fractionSize);

      //get the decimalSepPosition
      var decimalIdx = formattedValue.indexOf(formats.DECIMAL_SEP);

      //If no decimal just return
      if (decimalIdx == -1) return formattedValue;


      var whole = formattedValue.substring(0, decimalIdx);
      var decimal = (Number(formattedValue.substring(decimalIdx)) || "").toString();

      return whole +  decimal.substring(1);
    };
  }
]);

And use it as:

  <div ng-repeat="i in myList">{{i | numberEx:2}}</div>

Demo

angular.module('app', []).controller('ctrl', function($scope) {

  $scope.myList = [0, 10000.56, 0.5, 0.6666666, -1000.23123, 1, 1002, 2.5, 30.5, 22];

}).filter('numberEx', ['numberFilter', '$locale',
  function(number, $locale) {

    var formats = $locale.NUMBER_FORMATS;
    return function(input, fractionSize) {
      //Get formatted value
      var formattedValue = number(input, fractionSize);

      //get the decimalSepPosition
      var decimalIdx = formattedValue.indexOf(formats.DECIMAL_SEP);
      
      //If no decimal just return
      if (decimalIdx == -1) return formattedValue;

 
      var whole = formattedValue.substring(0, decimalIdx);
      var decimal = (Number(formattedValue.substring(decimalIdx)) || "").toString();
      
      return whole +  decimal.substring(1);
    };
  }
]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="ctrl">
  <div ng-repeat="i in myList">{{i | numberEx:2}}</div>
</div>
like image 111
PSL Avatar answered Oct 21 '22 02:10

PSL


I would do it like this:

<div ng-repeat="i in myList">{{formatNumber(i)}}</div>

and in your controller:

$scope.formatNumber = function(i) {
    return Math.round(i * 100)/100; 
}
like image 16
inorganik Avatar answered Oct 21 '22 04:10

inorganik


As the other answers didn't really work well, or did not not incorporate or work with Angular's $locale service, I wrote the following filter:

Template:

<span>{{yourNumber | roundTo: N}}</span>

Filter:

app.filter('roundTo', function(numberFilter) {
    return function(value, maxDecimals) {
        return numberFilter((value || 0)
            .toFixed(maxDecimals)
            .replace(/(?:\.0+|(\.\d+?)0+)$/, "$1")
        );
    }
})

  • Rounds the number to the max number of decimals

  • Trims all trailing zero's

  • Removes the decimal seperator when it's not needed

  • And Uses Angular's $locale formatting

like image 1
Jeffrey Roosendaal Avatar answered Oct 21 '22 02:10

Jeffrey Roosendaal