I am trying to use intl to do some formatting but no matter what I pass in as the locale, I always get the following error message:
ReferenceError: No locale data has been provided for this object yet
I have tried the following:
new Intl.NumberFormat('en-ZA', { minimumFractionDigits: percentDecimals });
as well as
new Intl.NumberFormat(['en-ZA'], { minimumFractionDigits: percentDecimals });
and I am not sure what else do.
I have added the package to the package.json
"intl": "latest"
and I do import it
import Intl from "intl";
Depending on the enviromnent you are running this code you might need to import locale data as well to polyfill locale
import 'intl/locale-data/jsonp/en-ZA'
This import does side-effect that register en-ZA locale IntlPolyfill.__addLocaleData({locale:"en-ZA", when polyfill is required.
For me it was solved by importing the "intl" at the top of the source code of the app.
In my case I was doing the import in (i18n.ts).
(i18n.ts) is where i18next is initialized. Then I have to move the import to the App.tsx.
// Polyfill Intl as it is not included in RN
import "intl";
Related
Our project is using i18next for translations, and I'm currently needing to sort strings using String.prototype.localeCompare
How would I go about getting a code like 'en', 'fr', 'en-US', etc from i18next? Does i18next default to a specific code? Would I need to use an i18next instance or the default export?
I believe these might be called "BCP 47 language tags"
Thanks
Ok, so the brief answer is that you just use i18next.language
In our case, it did matter that we used the correct instance, not just the default import. We also used an additional layer called react-i18next as shown below.
import { I18nContext } from "react-i18next";
...
const { i18n } = useContext(I18nContext);
...
return isLocaleCompareSupported()
? aText.localeCompare(bText, i18n.language)
: aText.localeCompare(bText);
I'm using React Intl for x number of languages (example below) and at the moment Im importing the following where I setup my App:
import { addLocaleData } from 'react-intl';
import locale_en from 'react-intl/locale-data/en';
import locale_de from 'react-intl/locale-data/de';
import messages_en from './translations/en.json';
import messages_de from './translations/de.json';
addLocaleData([...locale_en, ...locale_de]);
...
export const messages = {
en: messages_en,
de: messages_de
}
Since these language files are being imported no matter which language is being used my main bundle js file is getting pretty big, especially from the .json files.
How can I with Webpack split these language files (or copy them to my dist folder using CopyWebpackPlugin) and then dynamically import them based on the language being used at the moment?
The app is isomorphic so this same code is being run on the server.
I've been working on something like this lately, although I don't need SSR for my project. I found that pairing dynamic import syntax with React's Suspense component achieves the desired result. Here's a rough overview of what I found to work, at least in my case, which doesn't include SSR:
// wrap this around your JSX in App.js:
<React.Suspense fallback={<SomeLoadingComponent />}>
<AsyncIntlProvider>
{/* app child components go here */}
</AsyncIntlProvider>
</React.Suspense>
// the rest is in support of this
// can be placed in another file
// simply import AsyncIntlProvider in App.js
const messagesCache = {};
const AsyncIntlProvider = ({ children }) => {
// replace with your app's locale getting logic
// if based on a hook like useState, should kick off re-render and load new message bundle when locale changes (but I haven't tested this yet)
const locale = getLocale();
const messages = getMessages(locale);
return (
<IntlProvider locale={locale} messages={messages}>
{children}
</IntlProvider>
);
};
function getMessages(locale) {
if (messagesCache[locale]) {
return messagesCache[locale];
}
// Suspense is based on ErrorBoundary
// throwing a promise will cause <SomeLoadingComponent /> to render until the promise resolves
throw loadMessages(locale);
}
async function loadMessages(locale) {
// dynamic import syntax tells webpack to split this module into its own chunk
const messages = await import('./path/to/${locale}.json`);
messagesCache[locale] = messages;
return messages;
}
Webpack should split each locale JSON file into its own chunk. If it doesn't, something is likely transpiling the dynamic import syntax to a different module system (require, etc) before it reaches webpack. For example: if using Typescript, tsconfig needs "module": "esnext" to preserve import() syntax. If using Babel, it may try to do module transpilation too.
The chunk output for a single locale will look something like this; definitely more than would be achieved via CopyWebpackPlugin:
(window["webpackJsonp"] = window["webpackJsonp"] || []).push([[0],{
/***/ "./path/to/en-US.json":
/*!*************************************!*\
!*** ./path/to/en-US.json ***!
\*************************************/
/*! exports provided: message.id, default */
/***/ (function(module) {
eval("module.exports = JSON.parse(\"{\\\"message.id\\\":\\\"Localized message text\\\"}\");//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9zcmMvbG9jYWxpemF0aW9uL2VuLVVTLmpzb24uanMiLCJzb3VyY2VzIjpbXSwibWFwcGluZ3MiOiIiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./path/to/en-US.json\n");
/***/ })
}]);
Hopefully, this is a good starting point and either works with SSR or can be modified to work with SSR. Please report back with your findings on that subject. 🙂
I want to use import in my file, but I cant find the way to replace my require properly
See the code I want to replace
const object = {
first: require('../example/first.json').EXL.PUBLIC,
second: require('../example/second.json').EXL.PUBLIC,
third: require('../example/third.json').EXL.PUBLIC
}
First question is how can I import those stuff directly to an object? Just like I did with require?
The second one, how can I use import with the .EXL.PUBLIC command? To directly import the right branch of the json file?
First question is how can I import those stuff directly to an object?
You can't, you have to import them and then add them to the objct.
The second one, how can I use import with the '.EXL.PUBLIC' command?
You have to import the item, then extract that property.
I'm going to assume you're using Node.js:
v8 through v11
In an .mjs module, you can do it like this:
import firstRoot from "../example/first.json";
import secondRoot from "../example/second.json";
import thirdRoot from "../example/third.json";
const object = {
first: firstRoot.EXL.PUBLIC,
second: secondRoot.EXL.PUBLIC,
third: thirdRoot.EXL.PUBLIC
};
v12
You can still do it as in v11.
If you use ESM with a .js file via the new "type": "module" in package.json, you need to add the --experimental-json-modules flag to enable JSON loading. More about v12's support here, but note that --type isn't yet supported (and if it is, will probably be --entry-type), and the JSON flag is --experimental-json-modules, not --experimental-json-loader).
I want to use the validator for an express project. How do I import just two subsets of the packages directly?
Like:
import {isEmail, isEmpty} from 'validator';
or importing each on a separate line.
I just want to know if there is another option apart from import validator from 'validator'; as stated on the https://www.npmjs.com/package/validator
const isEmailValidator = require('validator').isEmail;
const isEmptyValidator = require('validator').isEmpty;
isEmailValidator('bla#bla.com');
Like this you mean? What you wrote should also be valid:
import {isEmail, isEmpty} from 'validator';
isEmail('bla#bla.com');
Edit for clarification: As you can see here https://github.com/chriso/validator.js/blob/master/src/index.js the library is exporting an object with each function. You can import everything import validator from 'validator' or you can use destructuring to get only a few properties.
const {isEmail, isEmpty} = require('validator');
This will not actually stop node from importing all of validator though. This just has node load the validator object that is returned from that modules export and then destructures isEmail and isEmpty out of the exported Object.
Maybe whenever ES6 modules become full supported you can use the regular import syntax. See node.js documentation: ECMAScript Modules.
I am learning Angular 2 and I followed the tutorials of Egghead already, but I am pretty new to everything concerning Angular.
Now I want to do something more advanced and start using Parse.com with Angular 2.
Normally I would include the parse.com library in the index.html page via <script src="//www.parsecdn.com/js/parse-1.6.2.min.js"></script>, but I want to write a ParseService via Angular 2 that I can use to manage the backend.
I can't seem to find how to include and use Parse in the service I want to write.
This is the very basic code I want to use to test the import.
import {Injectable} from 'angular2/core';
import {Parse} from '.../...'; // <-- This is what I want to do
#Injectable()
export class ParseService {
constructor() {
console.log('Creating ParseService');
Parse.initialize('', '');
}
}
I need some kind of Import at the top of the page including Parse, but from where should I get the necessary library? I already tried via npm but without success. Anyone already tried this?
uksz was right. You has to first install the component by the command
npm install --save parse
After that you can import it as any other component by typing
import {Parse} from 'parse';
For more info look at this link https://forum.ionicframework.com/t/how-to-require-xyz-in-ionic2-angular2/42042
Hope it helps;)
UPDATED
With new version of angular this approach stopped to work. Here is my new step by step: how to use Parse library in Angular2
Install Parse component to the project
npm install parse --save
Install Parse types
npm install #types/parse --save
import Parse module
const Parse: any = require('parse');
use Parse module
Parse.initialize("key");
...
Enjoy it with intellisense;)
You can do that by using OpaqueToken in Angular2
1. Create a Token that is used to find an instance as below in a separate ts file.
import { OpaqueToken } from '#angular/core'
export let name_of_The_Token = new OpaqueToken('name_Of_The_Window_Object');
2. In your App.module, you need to import and declare a variable that is the name of your window object which makes the Token as a angular2 service so that you can use properties, methods in that javascript file across your components.
import { name_of_The_Token } from '/* file_Path */';
declare let name_Of_The_Window_Object : any; //below your import statements
Step 3: Inject it to providers array of your module.
{ provide : name_of_The_Token , useValue : name_Of_The_Window_Object }
Guidance to use this token in components
Import the token just like any other service and #Inject from angular-core
import { name_of_The_Token } from '/* file_Path */';
import { Inject } from '#angular/core';
In constructor of the component
constructor(#Inject( name_of_The_Token ) private _serviceObject : any )
Any where in your component you can use the variables and methods of your javascript file as
this._serviceObject.method1()
this._serviceObject.variable1
.....
Note: One drawback is that you will not get intellisense.
Overcoming it:
If you are looking for intellisense you need to wrap the methods and variables inside an interface and use it in the type**(instead of any)** of your token as
export interface myCustom {
method1(args): return_Type;
method2(args): void;
.....
}
What you need to do, is you need to download Parse library with:
npm install parse
Then, you need to reference it in your import in the right way - you need to specify in which folder the parse.js file is placed at.