45

Can I set $locale for some application manually?

Is it possible that only way to support locals is to include localization file from angular library for current locale. What if there are multiple cultures? In that case I have to load localization files dynamically? What am I missing?

Andrej Kaurin
  • 11,592
  • 13
  • 46
  • 54

11 Answers11

32

You can load the locale you want into localStorage, then refresh the page. Have the script below load the i18n file you need. Changing the locale on the fly isn't supported yet.

<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.3/angular.min.js"></script>
<script>
var locale = JSON.parse(localStorage.getItem('locale'));
if (locale) {
    document.write('<script src="scripts/i18n/angular-locale_'+locale+'.js"><\/script>');
}
</script>
Jonn
  • 1,594
  • 1
  • 14
  • 25
will Farrell
  • 1,733
  • 1
  • 16
  • 21
  • This worked for me. I did have to change "angular-locale_" to "angular-locale\\_", though (escaping the underscore). – Jonn May 29 '14 at 16:22
  • Worked like a charm, no server side code required, well accepted by angular. This is a really time saving solution! – Matteo Conta Mar 14 '16 at 14:41
  • This worked for me. I was struggling with all other options for a long time. – Dilhan Jayathilake Aug 27 '16 at 11:22
  • 1
    This fix requires refresh of the page. For first load of the page you can simply get browser language through window.navigator object as a fallback. – Vlada Mar 01 '17 at 09:22
31

I've built an angular module that takes care about i18n. AngularJS support for i18n is pretty primitve, if you want to have more control and also be more flexible, checkout angular-translate - http://angular-translate.github.io/

Let me know, if I can help out!

Kariem
  • 4,398
  • 3
  • 44
  • 73
Pascal Precht
  • 8,803
  • 7
  • 41
  • 53
24

For anyone looking for dynamic localization today angular-dynamic-locale does a great job.

23

I struggled with the same issues, read all the answers here and introduced i18n/l10n in my project. This are my outcomes:

So the solution is to use both projects, angular-translate and angular-dynamic-locale.

Ursin Brunner
  • 2,310
  • 1
  • 24
  • 24
15

Honestly, the $locale service in angular is pretty primitive still. It's really good, but it seems to lack flexibility in this area. The biggest issue is that even if you switch your locale by dynamically reloading the proper locale file, things like the date filter won't know you've changed it because they're registering their locale information when they're set up. So you have a couple of choices currently: 1. Reload the page with the selected locale... or 2. Write your own Locale Provider and Filters that use it.

It might be possible create a service that would dynamically load the proper script file, reinitialize all affected filters and services, then refresh the views, but I'm not really sure what all that would involve at this point.

Ben Lesh
  • 107,825
  • 47
  • 247
  • 232
  • Thanks,I like control so I am going to write my own custom Locale Provider. – Andrej Kaurin Oct 22 '12 at 15:53
  • 1
    You could probably have your LocaleProvider match the signature of the original one, but have JavaScript property setters and getters on each item in the locale to allow you to programmatically check whatever locale you need to. – Ben Lesh Oct 22 '12 at 15:57
  • 1
    I've written a custom locale provider but it only takes effect on date filters, both number and currency capture their formats in a closure. – Marius Soutier Aug 09 '13 at 14:32
  • 5
    @MariusSoutier is that custom locale provider something you can share? I am looking at this same problem – Kevin Hakanson Aug 17 '13 at 14:51
2

Including this script: https://github.com/lgalfaso/angular-dynamic-locale/blob/master/src/tmhDynamicLocale.js enables locales to be set during run time.

  1. Download all the locales you want from https://github.com/angular/angular.js/tree/master/src/ngLocale
  2. Store the locales in a directory on your web server, e.g. /assets/js/locales/filename-LOCALE.js - note: what you write as the LOCALE in the filename is important - any locales required will get downloaded dynamically.
  3. In your module, include tmhDynamicLocale as 'tmh.DynamicLocale' e.g. var app = angular.module('app',['tmh.DynamicLocale']);
  4. In your config, pass in the provider i.e. 'tmhDynamicLocaleProvider' and set the location of your locale files, e.g. tmhLocaleProvider.localeLocationPattern('/assets/js/locales/angular-locale-{{locale}}.js'); {{locale}} will be swapped out for the locale you set at run time.
  5. To set the locale across your app, in app.run(), pass in the 'tmhDynamicLocale' service e.g. app.run(['tmhDynamicLocale',function(tmhDynamicLocale){}]);
  6. In your run callback, set the locale like this, tmhDynamicLocale.set('en-gb');. Alternatvely, as tmhDynamicLocale is a service, you could set the locale in different places service injections are allowed, e.g. controllers, although bear in mind, services are singletons, and setting the locale in a controller will set it across the app.

You should now have the correct locale running. For further info, use the README for tmhDynamicLocale:https://github.com/lgalfaso/angular-dynamic-locale/blob/master/README.md

Credit: Lucas Mirelmann for tmhDynamicLocale.

dewd
  • 4,380
  • 3
  • 29
  • 43
1

I found something interesting. It is not angular but it is jquery so integration should be ok. I will test performances and get back with info.

https://github.com/js-coder/x18n/wiki/Getting-started

https://github.com/js-coder/jQuery.x18n

Andrej Kaurin
  • 11,592
  • 13
  • 46
  • 54
  • 1
    I found it complex to implement so I finished with simple service that loads resources from server and caches it. For translation to be shown I used simple directive. – Andrej Kaurin Feb 28 '13 at 14:35
1

If you want to load the angularJS localization of your browser, install https://github.com/angular/bower-angular-i18n and https://github.com/lgalfaso/angular-dynamic-locale in your project.

Read the documentation of each library to install. This is an example of my Ionic project:

  1. In my index.html:

    ...
    <!-- angular-dynamic-locale-->
    <script src="lib/angular-dynamic-locale/tmhDynamicLocale.min.js"></script>
    ...
    
  2. In my app.js

    var app = angular.module('project-name', ['ionic',..., 'tmh.dynamicLocale']);
    ...
    // tmhDynamicLocaleProvider
    app.config(function(tmhDynamicLocaleProvider) {
       //  override the default path (angular/i18n/angular-locale_{{locale}}.js) to the stored Angular i18n locale files
       tmhDynamicLocaleProvider.localeLocationPattern('lib/angular-i18n/angular-locale_{{locale}}.js');
    })
    ...
    app.run(function($rootScope, $ionicPlatform, ..., tmhDynamicLocale){
       // set locale for angular formats   
       var inArray = function(needle, haystack) {
          var key = '';
          for (key in haystack) {
             if (haystack[key] === needle) {
                return true;
             }
          }
          return false;
       };
       var preferredLanguage = navigator.language || navigator.browserLanguage || navigator.systemLanguage || navigator.userLanguage;
       if (typeof preferredLanguage === 'string') {
          var code = preferredLanguage.substring(2, 0);
             if (inArray(code, PROPERTIES.LANGUAGES)) {
                tmhDynamicLocale.set(code);
             }
       }
       ...
    
pablo.nunez
  • 124
  • 1
  • 5
0

Angular provide great support for i18n/l10n. You can find the guide here

The requirements for our application determines how we can implement this support.

  1. If our application requires only a single locale or the end users of our application belongs only to a particular locale then we can restrict our application scope for i18n/l10n to only that locale

You can find a good explanation of how we can achieve such things in one of my previous answers here.

  1. If we want to serve a particular component, directive or part to display in some other format or locale then we can go for some directives components or even a filter for that

You can find an example fiddle for such implementation using a filter can be found here

 function MyController($scope) {
   $scope.property = {
     price: 50000000.557
   }
 }

 function toLocaleCurrencyFilter($filter) {
  return function(amount, currencySymbol, fractionSize, locale) {
    var returnValue = Number(parseFloat(amount)).toLocaleString(locale, {
      minimumFractionDigits: parseInt(fractionSize),
      maximumFractionDigits: parseInt(fractionSize),
    });
    returnValue = returnValue + " " + currencySymbol
    return returnValue;
  };
 }
 angular.module('myApp', [])
   .controller('MyController', ['$scope', MyController])
   .filter('toLocaleCurrency', ['$filter', toLocaleCurrencyFilter]);
  1. If we want dynamic locale then you need to reload browser with the new locale settings by saving it into local storage to take effect. you can use the solution described in 1 with some dynamic nature.
SAMUEL
  • 8,098
  • 3
  • 42
  • 42
0

If you are using webpack and typescript, you can load your locale dynamically.

    export const loadLocale = function(lng){
    if(lng != 'en'){
        require('./angular-locale_' + lng + '.js');
    }
};
httpete
  • 2,765
  • 26
  • 34
-1

you can also use the translation service to get the browser's locale then use it to do what you need. . . for example, in a ShortDatePipe:

   import { Pipe, PipeTransform} from '@angular/core';
    import { formatDate  } from '@angular/common';
    import { TranslateService } from '@ngx-translate/core';

    @Pipe({
      name: 'shortDate'
    })
    export class ShortDatePipe implements PipeTransform {
        constructor(private translateService: TranslateService) { }

        transform(value: string): string {
            var language: string = this.translateService.getBrowserCultureLang();
            console.log(language);
            return (value == "" || value == null) ? "" : formatDate(value, 'shortDate', language);
        }

    }
Mike A.
  • 1,438
  • 13
  • 11