angular-dynamic-locale
angular-dynamic-locale copied to clipboard
Sync loading with Webpack
I was looking into preloading a few locales so that async loading wouldn't be required (I'm using this in cordova so it wouldn't make much sense) and I came up with this:
function getInjectedLocale() {
var localInjector = angular.injector(['ngLocale']);
return localInjector.get('$locale');
}
// put de-de language into cache
require('angular-i18n/de-de');
tmhDynamicLocaleCache.put('de-de', getInjectedLocale());
// put en-gb language into cache
require('angular-i18n/en-gb');
tmhDynamicLocaleCache.put('en-gb', getInjectedLocale());
// later on:
tmhDynamicLocale.set('en-gb'); // or de-de
Seems to work very well, I'm leaving this here as a possible addition to the readme. A possible improvement might be to create a method in tmhDynamicLocale
, like tmhDynamicLocale.cacheLastLoadedLocale('de-de')
for instance, which can be called right after the require
.
@andreialecu thanks!
@andreialecu This is something I need as well, but could you please elaborate further on how to achieve this or point me to a working plunker / ? I am sure I might wrap my head around it, but if you have any clues (where (files), when (phase) to use your above code), that would be helpful...
@ChristianUlbrich The above code assumes you're using webpack.
You can just put it inside a .run
call like this:
app.run(function(tmhDynamicLocale, tmhDynamicLocaleCache) {
...
});
If you're not using webpack, then I'm not sure how this helps you or why you would need it. Care to elaborate?
@andreialecu Thanks! That's all I needed. Sorry, for using "elaborate" :) Actually I can only guess, why your approach works, but do I care? No! Works like a charm.
And yes we are using webpack and I need to pre-bundle the available locales, just like you wanted to.
If I were to wish for something, I think that the localeCache should be synchronously set by a provider.
You're welcome! English is not my first language but I don't think there's anything wrong with the word "elaborate", I just wasn't sure what you were asking, that is all. :)
This chunk of code was helpful to get started but I took another path with webpack to tackle async issues. It's using ui-router.
In webpack make a bare copy of the locals so they are packaged but not (yet) imported.
var copyStatic = new CopyWebpackPlugin([
{from: './node_modules/angular-i18n/angular-locale_de-de.js', to: path.resolve(APP_ROOT, appConfig.buildDir + '/i18n')},
{from: './node_modules/angular-i18n/angular-locale_en-gb.js', to: path.resolve(APP_ROOT, appConfig.buildDir + '/i18n')},
]);
Set the path to the locales in the angular config.
tmhDynamicLocaleProvider.localeLocationPattern('i18n/angular-locale_{{locale}}.js');
Finally created a ui-router hook to make sure that the locale is always set before your logic starts executing.
$transitionsProvider.onBefore({}, setLocale, { priority: 20 });
function setLocale(transition) {
const tmhDynamicLocale = transition.injector().get('tmhDynamicLocale');
return tmhDynamicLocale.set('fr')
.catch((err) => {
console.warn('Error setting locale. Using default locale.', err);
});
}
Here is how I did it with dynamic imports:
let inject = (lang) => tmhDynamicLocaleCache.put(lang, angular.injector(['ngLocale']).get('$locale'));
$q.all([
System.import('angular-i18n/angular-locale_de')
.then(() => inject('de')),
System.import('angular-i18n/angular-locale_en')
.then(() => inject('en')),
System.import('angular-i18n/angular-locale_es')
.then(() => inject('es')),
System.import('angular-i18n/angular-locale_fr')
.then(() => inject('fr')),
System.import('angular-i18n/angular-locale_pl')
.then(() => inject('pl')),
System.import('angular-i18n/angular-locale_pt')
.then(() => inject('pt'))
]).then(() => tmhDynamicLocale.set('en'));