Nativescript: toLocaleString() doesn't localise the number

Created on 15 Jan 2020  Â·  5Comments  Â·  Source: NativeScript/NativeScript

Environment
Provide version numbers for the following components (information can be retrieved by running tns info in your project folder or by inspecting the package.json of the project):

  • CLI: ?
  • Cross-platform modules: ?
  • Android Runtime: ?
  • iOS Runtime: ?
  • Plugin(s): ?

I'm running the latest version of everything (the project is a month old), but couldn't find any version numbers matching the mentioned packages in with either tns info or by looking in my package file.

Describe the bug

To format nice readable numbers all modern browsers support the function toLocaleString, which helps adding localised thousand separators, decimal separators, rounding of decimals, padding of decimals and a lot more.
In NativeScript this functions returns the same value as toString which doesn't support any of the mentioned features.

To Reproduce

const someNumber = 1337.4242
const formattedNumber = someNumber.toLocaleString('en', {maximumFractionDigits: 2})

Expected behavior
formattedNumber should now contain the string 1,337.42
Instead it contains the string 1337.4242

Sample project

I don't have a sample project, but expect the behaviour to be the same in alle projects.

Additional context

We could implement a formatting function ourself, but because of code sharing between projects, it would also mean that this custom formatter would be used in our web based projects, which seems a bit silly, since the browsers already know how to format numbers.

Documentation for the browser implementation can be found here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toLocaleString

android

All 5 comments

NativeScript uses JavaScriptCore VM (for Android) which has a known issue with toLocalString. So that said, there is not much that can be done on the NativeScript side.. you could look for a custom formatter to handle this case.

That's sad :'( (not that your'e using a third party, but that they have issues)...

I'm experiencing the bug on iOS too — is it the same JS core?

Not sure if the issue on iOS is the same (the VM is V8 so - no, this is a different VM). Byt the way the VMs are not a third-party library (like a plugin) but the core engines that are handling the runtimes. So the same issue is present in react-native (as they are also using JavaScriptCore for Android).

Here's a temporary workaround, obviously not the best solution but it works in Nativescript-Vue:

     var sampleNumber = 123456789;

      return (
        "$" +
          sampleNumber
          .toString()
          .split("")
          .reverse()
          .map((number, index, array) => {
            return (index + 1) % 3 === 0 && array[index + 1]
              ? `,${number}`
              : number;
          })
          .reverse()
          .join("")

Here's a temporary workaround, obviously not the best solution but it works in Nativescript-Vue:

     var sampleNumber = 123456789;

      return (
        "$" +
          sampleNumber
          .toString()
          .split("")
          .reverse()
          .map((number, index, array) => {
            return (index + 1) % 3 === 0 && array[index + 1]
              ? `,${number}`
              : number;
          })
          .reverse()
          .join("")

This almost works, the only problem is that we lose the decimal part (example: 1000.00 turns into $ 1,000)
EDIT: Fixed it:

function format(value) {
  const decimalPart = value.toFixed(2).split('.')[1]
  return (
    '$ ' +
      value
      .toString()
      .split('.')[0]
      .split('')
      .reverse()
      .map((number, index, array) => {
        return (index + 1) % 3 === 0 && array[index + 1]
          ? `,${number}`
          : number;
      })
      .reverse()
      .join('')
      + '.' + decimalPart
  )
}
Was this page helpful?
0 / 5 - 0 ratings