Question

I need to print very small numbers for my app. I prefer if they were all displayed in decimal format. Is there a way to do this with the angularjs number filter or do I have to write my own or modify the existing one somehow?

http://jsfiddle.net/ADukg/2386/

Javascript

var myApp = angular.module('myApp',[]);

 function MyCtrl($scope) {
   $scope.MyNum1 = 0.000001;
   $scope.MyNum2 = 0.0000001;
 }

HTML

<div ng-controller="MyCtrl">
  Small Number: {{MyNum1 | number:8}}<br/>
  Very Small Number: {{MyNum2 | number:8}}
</div>

Inconsistent Output

Small Number: 0.00000100
Very Small Number: 1e-7
Was it helpful?

Solution

I haven't fully tested this and I'm not sure how to get this working on jsfiddle, but this seems to be working for the time being.

Javascript

var app = angular.module('myApp', []);

app.filter('decimalFormat', function () {
  return function (text) {
    return parseFloat(text).toFixed(20).replace(/0+$/,'');
  };
});

HTML

<div ng-controller="MyCtrl">
  Small Number: {{MyNum1 | number:8 | decimalFormat}}<br/>
  Very Small Number: {{MyNum2 | number:8 | decimalFormat}}
</div>

Edit after Langdon's comment, added commas:

Javascript

var app = angular.module('myApp', []);

app.filter('decimal', function () {
  return function (text) {
      var parts = parseFloat(text).toFixed(8).split('.');
      parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ',');
      return parts.join('.');
    }
  };
});

function MyCtrl($scope) {
  $scope.MyNum1 = 0.12345678912;
  $scope.MyNum2 = 0.000000100001;
  $scope.MyNum3 = 0;
  $scope.MyNum3 = 1123123.05;
}

HTML

<div ng-controller="MyCtrl">
  Small Number: {{MyNum1 | decimal}}<br/>
  Very Small Number: {{MyNum2 | decimal}}<br/>
  Zero: {{MyNum3 | decimal}}<br/>
  Million: {{MyNum4 | decimal}}<br/>
</div>

OTHER TIPS

You're going to have to write your own since the existing filter in the source doesn't handle large decimal places (see formatNumber in the filters.js). Ultimately the problem is that toString is called to display the number in your HTML. More ideally, toFixed could be called, but that gets tricky because you have to figure out the length of the decimals.

console.log(0.000001);
 > 0.000001
console.log(0.0000001);
 > 1e-7
console.log(0.0000001.toFixed(20));
 > 0.00000010000000000000

Here's a quick hack:

console.log(0.0000001.toFixed(20).replace(/0+$/, ''));
 > 0.0000001

So your custom filter could be as simple as that. I'd recommending filing an issue on GitHub though.

This was made to return large numbers as decimal strings, but it works as well for small ones-

Number.prototype.noExponents= function(){
    var data= String(this).split(/[eE]/);
    if(data.length== 1) return data[0]; 

    var  z= '', sign= this<0? '-':'',
    str= data[0].replace('.', ''),
    mag= Number(data[1])+ 1;

    if(mag<0){
        z= sign + '0.';
        while(mag++) z += '0';
        return z + str.replace(/^\-/,'');
    }
    mag -= str.length;  
    while(mag--) z += '0';
    return str + z;
}

var n=1e-7;
n.noExponents();
returned value: (String) '0.0000001';
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top