React-native: toLocaleString straight up doesn't work on Android

Created on 23 May 2018  ·  11Comments  ·  Source: facebook/react-native

there are a bunch, but the most recent seems to have been unceremoniously closed 🤐
see also

Description

I would like to render a number as a properly formatted currency string.

I would also like the implementation to behave the same across both iOS and Android.

Sample code:

const someNum = 1000;

const App = () => (
  <View style={styles.container}>
    <Text>
      {someNum.toLocaleString('en-US', { style: 'currency', currency: 'USD' })}
    </Text>
  </View>
);

// iOS: $1,000
// Android: 1000

Environment

Environment:
  OS: macOS High Sierra 10.13.4
  Node: 10.1.0
  Yarn: 1.6.0
  npm: 6.0.1
  Watchman: 4.9.0
  Xcode: Xcode 9.3.1 Build version 9E501
  Android Studio: 2.3 AI-162.4069837

Packages: (wanted => installed)
  react: 16.3.1 => 16.3.1
  react-native: 0.55.4 => 0.55.4

Steps to Reproduce


Expo Snack

Expected Behavior


I thought it would return '$1,000' on both iOS and Android.

Actual Behavior


This only works on iOS; in this example no formatting happens at all on Android.

Screenshots

Android

screen shot 2018-05-23 at 4 49 25 pm

iOS

screen shot 2018-05-23 at 4 49 34 pm

Author Provided Repro JavaScript Android Locked

Most helpful comment

No temple gods answering yet i see...

The problem still there, sacrifice another goat? Maybe a bigger one?

All 11 comments

No temple gods answering yet i see...

The problem still there, sacrifice another goat? Maybe a bigger one?

Airbnb wrote a blog post that mentioned this issue. It seems to be caused by Android running an outdated version of JavaScriptCore.

There's another issue open that's discussing a potential JSC update: #19737

As a workaround, you can use this:
https://github.com/react-community/jsc-android-buildscripts

@rgabriel18 I lol'd a lot.

Hey there, it looks like there has been no activity on this issue recently. Has the issue been fixed, or does it still require the community's attention? This issue may be closed if no further activity occurs. You may also label this issue as "For Discussion" or "Good first issue" and I will leave it open. Thank you for your contributions.

This issue still exists.

This is an issue with Javascript core used to run react native in Android and not with react native itself. To overcome this, you'll have to integrate latest javascript core into your android build or upgrade react native to 0.59.

The details are documented in JSC Android Buildscripts repo. You can actually close this issue.

Now for people who would like to do the locale string formatting without needing to integrate the entire javascript core, Javascript has Internationalization API which lets you format numbers to language sensitive format. Documentation available at MDN

This API is not available in android and needs to be polyfilled using Intl

In your project root, install the Intl library

yarn add intl

And then in your project's index file (index.js) add the following code at the top of the file:

if(Platform.OS === 'android') { // only android needs polyfill
  require('intl'); // import intl object
  require('intl/locale-data/jsonp/en-IN'); // load the required locale details
}

After doing the above two steps, you can now get locale string anywhere in your project using

new Intl.NumberFormat('en-IN', { style: 'currency', currency: 'INR' }).format(10000000);

In case you need to format number for another locale code, all the locale code details are available under the intl/locale-data/jsonp/ directory. Simply require the ones you need in your index.js file. Hope it helps.

And the fucking issue still exist

Since Facebook locked and closed
https://github.com/facebook/react-native/issues/15717 and this is being discussed elsewhere, I'm following suit and closing this off 🙇🏻‍♂️

``` const _ = require('lodash');

export function roundValue(value) {
return _.round(value, 2).toLocaleString('eu', {
style: 'currency',
currency: 'EUR',
});
}

Here is the function I used to display localized price for EUROPE. This only works on ios.

To make it work on Android 
just install `intl` using `npm install intl`

And then in your project's index file (index.js) add the following code at the top of the file:

import { Platform } from 'react-native';

if (Platform.OS === 'android') {
require('intl');
require('intl/locale-data/jsonp/fr-BE');
require('intl/locale-data/jsonp/nl-BE');
require('intl/locale-data/jsonp/it-IT');
}
```

It now works for both android and ios.

Thanks to @DaniAkash locale now works. But i use it for dates and had another issue with the timeZone option of Date​​.toLocale​String().
Error was timeZone is not supported. I used yahoo/date-time-format-timezone to fix it. Steps:

  1. npm i intl and npm i date-time-format-timezone
  2. In index.js add the following lines above of AppRegistry.registerComponent(appName, () => App)
import { Platform } from 'react-native'

if (Platform.OS === 'android') {
  require('intl');
  require('intl/locale-data/jsonp/en-US');
  require('intl/locale-data/jsonp/tr-TR');
  require('date-time-format-timezone');
  Intl.__disableRegExpRestore();/*For syntaxerror invalid regular expression unmatched parentheses*/
}
  1. Now i can use it like
    new Date().toLocaleString("tr-TR", { timeZone: 'Europe/Istanbul' })

Hope this helps others too.

Use this method instead of using toLocaleString :

number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")

https://stackoverflow.com/a/45084376/9248521

Was this page helpful?
0 / 5 - 0 ratings