Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Node: Cannot replace Intl to use IntlPolyfill

I'm trying to use Intl with pt-BR locale and I can't get that to work with Node 0.12.

Code:

global.Intl = require('intl/Intl');
require('intl/locale-data/jsonp/pt-BR.js');

var options = { year: 'numeric', month: 'long' };
var dateTimeFormat = new Intl.DateTimeFormat('pt-BR', options);
console.log(dateTimeFormat.format(new Date()));

This code outputs:

May, 2015

I would expect that to be: 'Maio, 2015'.

Then, if I decide to create a new variable, everything works:

Working Code:

global.NewIntl = require('intl/Intl');
require('intl/locale-data/jsonp/pt-BR.js');

var options = { year: 'numeric', month: 'long' };
var dateTimeFormat = new NewIntl.DateTimeFormat('pt-BR', options);
console.log(dateTimeFormat.format(new Date()));

This prints out the expect value. Question: Why the Intl global variable is not being replaced?

like image 680
Alan Souza Avatar asked Sep 16 '26 03:09

Alan Souza


2 Answers

Because the Intl property of the global object is not writable (testing on Node 0.12.2):

console.log(Object.getOwnPropertyDescriptor(global, 'Intl'));
/*
{ value: {},
  writable: false,
  enumerable: false,
  configurable: false }
*/

Put your code in strict mode and it will throw a more descriptive error when trying to assign to non-writable properties instead of failing silently.

It is also not configurable, so there is no way to fully replace (re-assign) the global.Intl. And this is a good thing: other modules and dependencies may depend on the built-in Intl implementation.

Tampering with the global scope most often results in more headache than it is worth, it is best to keep your packages self-contained. You can just require the polyfill in the files where you need it:

var Intl = require('intl/Intl');
// Note: you only need to require the locale once
require('intl/locale-data/jsonp/pt-BR.js');

var options = { year: 'numeric', month: 'long' };
var dateTimeFormat = new Intl.DateTimeFormat('pt-BR', options);
console.log(dateTimeFormat.format(new Date()));

You can then just add var Intl = require('intl/Intl'); in the files where you need Intl.

like image 87
Fabrício Matté Avatar answered Sep 17 '26 16:09

Fabrício Matté


It turns out that replacing only DateTimeFormat and NumberFormat solves the issue:

require('intl/Intl');
require('intl/locale-data/jsonp/pt-BR.js');
Intl.NumberFormat = IntlPolyfill.NumberFormat;
Intl.DateTimeFormat = IntlPolyfill.DateTimeFormat;

var options = { year: 'numeric', month: 'long' };
var dateTimeFormat = new Intl.DateTimeFormat('pt-BR', options);
console.log(dateTimeFormat.format(new Date()));

Just make sure to load this script before loading react-intl in case you are also using it.

I got this information from here.

like image 21
Alan Souza Avatar answered Sep 17 '26 17:09

Alan Souza



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!