9

I have a very simple lightning component taken straight from the aura docs that on initialization sets an attribute to a percentage. I noticed that the localization service rounds the value as opposed to adding a decimal according the scale of the percentage. This was noticed when using it in a more complex component where decimal points are required.

If decimals were included, the formats would be different.

US format = XX.X% French format = XX,X%

I do not see a param in the Aura documentation for adding scale and the CLDR states that there are patterns that have a percent leading, with most cases having the sign trailing: http://www.unicode.org/cldr/charts/30/by_type/numbers.number_formatting_patterns.html

The component and the two variations of the controller:

<aura:component >
<aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
<aura:attribute name="percent" type="string" />

<ui:outputText value="{!v.percent}" />

Controller - returns 54%:

({
     doInit: function(component) {
          var num = 0.5444
          // Returns 54%
          var formatted = $A.localizationService.formatPercent(num);
          component.set("v.percent", formatted);
      }
})

Controller - returns 55%:

({
     doInit: function(component) {
         var num = 0.5456
         // Returns 55%
         var formatted = $A.localizationService.formatPercent(num);
         component.set("v.percent", formatted);
     }
})
6

This would need to get fixed in aura itself to allow one to specify the decimal places.

Since percent is fairly standard across all localizations you could 'hack' it by adding this function to a helper, which just adjusts the localization format string for the NumberFormat it creates for percent:

({
  formatPercent: function(num, decimals) {
    var decimalString = '0.';
    while (decimals-- > 0) decimalString += '0';
    return $A.localizationService.getNumberFormat(
        $A.get("$Locale.percentFormat").replace('0', decimalString)
        ).format(num);
  }
})

and then your Controller becomes:

({
 doInit: function(component, event, helper) {
     var num = 0.5456
     component.set("v.percent", helper.formatPercent(num, 2));
     // returns 54.56%
 }
})

note that this solution will add zeros padded to the end if you do something like:

helper.formatPercent(0.233, 2);
// returns 23.30%

one could check the decimals places of the number passed in and limit the decimalString, but maybe not depending out how you want it to render.

  • This is something I thought about doing but didn't want to since the problem is with the service itself, as you mention. Your post convinced me. I went ahead and raised an issue with the Aura Framework git repo to get this resolved. Great interim solution. – jmdohn Dec 11 '16 at 19:47
0

You can try using ui:outputNumber and display relevant value based on the Locale

<ui:outputNumber aura:id="1" value="{!v.percent}" format="00.00%"/>

Full Code Listing

<aura:component implements="force:appHostable" access="global" >
<aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
<aura:attribute name="percent" type="string" />
<div>
<ui:outputText value="format=&quot;0.00%&quot; : " /> 
<ui:outputNumber aura:id="1" value="{!v.percent}" format="00.00%"/>
</div>
<div>
<ui:outputText value="format=&quot;%0.00&quot; : " />
<ui:outputNumber aura:id="2" value="{!v.percent}" format="%00.00"/>
</div>
</aura:component>

Controller

({
  doInit: function(component) {
      var num = 0.5444
      component.set("v.percent", num);
  }
})

Output

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.