Multilingual AngularJS Applications

AngularJs Multilingual Support

I want to share this article to apply multilingual capability for AngularJs applications. Here I would like to show you the implementation of “Multilingual for AngularJs Applications”.
Let's dive into that with a code snippet.

Required-Library

AngularJs provides us a $locale service use localization, but we cannot use that for a larger-level application where we need to show the translated content based on the user's selected language at run time and it will be useful to format the data for the specific language. Here we prefer the global concept like getting data from resource files.

I preferred to use angular-translate that provides a simpler way of doing it. Detailed API documentation has been given in the GitHub site as well. Here I will explain it with a procedure for doing it.

Create a project in ASP.NET Web Application with Index.html as the start-up page.

Download and reference the following JavaScript files in index.html page.

  • angular-min.js
  • angular-translate.js
  • angular-translate-loader-partial.min.js (When our application has so many sub-level modules preferred one to go, this will help to load JSON files for the sub modules asynchronously).

Structuring the application folders for an Angular app can be done either by feature or by type, here I did it by feature.


Figure 1: Application Folders

Design our required partials and controller files.

Create an app.js file that has an Angular app creation and configuration as in the following:

var app = angular.module('MultilingualApp', ['pascalprecht.translate', 'ui.router']);

  • pascalprecht.translate is the dependency that needs to be injected into our Angular module when using angular-translate.

Here we use state-level routing so ui.router needs to be injected.

Then set up the config section with two states as in the following:

  1. app.config(['$stateProvider', function($stateProvider)   
  2. {  
  3.     $stateProvider.state('Customer',   
  4.     {  
  5.         url: '/Customer',  
  6.         templateUrl: 'App/Customer/Partials/Customer.html',  
  7.         controller: 'CustomerController'  
  8.     });  
  9.     $stateProvider.state('Retailer',   
  10.     {  
  11.         url: '/Retailer',  
  12.         templateUrl: 'App/Retailer/Partials/Retailer.html',  
  13.         controller: 'RetailerController'  
  14.     });  
  15. }]);  
Customer and Retailer is the submodule's name for the application. Here we have done the initial level setup. Now let's look into the core of the article.

Create the necessary JSON files for keeping the translation content for each language per module as in the following: 


Figure 2: JSON File

Please add the following piece of code snippet to make your JSON files available in the  browser:
  1. <system.webServer>  
  2. <staticContent>  
  3. <mimeMap fileExtension=".json" mimeType="application/json"/>  
  4. </staticContent>  
  5. </system.webServer>
We wanted to do the multilingual asynchronously. The following code snppet will help us to do that, before that we need to inject $translateProvider and $translatePartialLoaderProvider into the app.config() level.
  1. $translatePartialLoaderProvider.addPart('Main');  
  2. $translateProvider.useLoader('$translatePartialLoader',   
  3. {  
  4.     urlTemplate: "Scripts/Locales/{part}/{lang}.json"  
  5. });  
  6. $translateProvider.preferredLanguage('en_US');
useLoader will find a path where our JSON files are residing and it loads our files asynchronously. Two things we need to understand is that part and lang are the properties where part is the sub-module name and lang is for specifying which language for the JSON file to be loaded.

The loading of JSON files for the module is determined by the addPart API provided by $translatePartialLoaderProvider. After the app is loaded I want to supply the translated strings for the main page so here I added Main for the module's JSON files to be loaded. In the controller level you need to inject $translatePartialLoader that is configured by $translatePartialLoaderProvider.

If the user does not select a language then the English language is the default.

Here I want to point out the following two things.
  • Getting translated data at html level (usual one).
  1. <p>{{'Customer_Content'|translate}}</p> , translate can be used as filter or directive  
  • Getting translated data from a JSON file at the controller level (using $translate service that needs to be injected at the controller).
  1. $translate('Main_RetailerHeading').then(function (translatedValue)  
  2. {  
  3. $rootScope.PageSubTitle = translatedValue;   
  4. });
Where Main_RetailerHeading is the key from the JSON file.
  • Before translating the content be sure that the submodule's JSON files are loaded. That will be done by $translateProvider.isPartAvailable(‘sub-module name’) that returns true if the given name is already loaded else returns false.
  • But if you change the language on the fly, the translated content won't be reflected soon until you again press the same module page when you get the content from the JSON file using the $translate service (this is where the decision needs to be made whether to prefer which of the preceding two ways).

Be sure that we use the addPart API for each of the controller files for confirming which sub-module's JSON files needs to be loaded on the fly. Whenever the preceding API is used, we will get a “translateProviderStructureChanged” event that can be handled at the app.run() level that helps to look up for the changes across the app module.

In the language selection click, we use $translate.use(‘language key’) that updates the translated strings to the selected language.

That's all guys. You can get the source code from the following link:

Multilingual-AngularJs

Reference article: http://blog.thoughtram.io/angular/2015/03/21/angular-and-i18n-the-new-world.html

If you have any questions, just drop your queries into the comments section and I'll try to help you out.

I hope you enjoyed this article. I always welcome your comments that improves my knowledge and keeps motivating me personally.