Search code examples
javascriptangularjscookiesstrutsangular-translate

Angular Translate - Get Translation Table


I'm trying to integrate the angular-translate module into my application.

I've gotten an asynchronous loader to work correctly, and it loads my language translations correctly.

The problem I'm running in to, however, is that our backend is based on Struts 1. We have a template that is included in each page load instead of the body content being swapped out like in a single-page application. This template is where we instantiate the angular app with angular.module and all the dependencies. After instantiation, I set up the translation provider:

myApp.config(['$translateProvider', function($translateProvider){
    $translateProvider.useUrlLoader('url/to/my/load/action.do');
    $translateProvider.determinePreferredLanguage();
}]);

Because this template is included on each page load, and the angular app is thus instantiated again after each page load, the translation provider is hitting my action on every page load to get the translations.

This wouldn't be a huge load on the backend because I've implemented caching, but the problem is the flashes of untranslated content on every page.

My proposed solution is as follows:

  • Have a controller that will catch the $translateLoadingEnd event fired by angular translate and put the translation table into a cookie with some expiration time

    myApp.controller('TranslationController', function($scope, $rootScope){
        $rootScope.$on('$translateLoadingEnd',function(event) {
            // Get the translation table and put it in a cookie
        });
    });
    
  • In the config, I will only set $translateProvider.useUrlLoader('url/to/my/load/action.do'); if the cookie does not exist or it has expired. To do this, I will have to get the cookie by injecting the cookies service into the config with something like the following (how to use cookiesProvider in angular config) and grabbing out the translation table:

    var $cookies;
    angular.injector(['ngCookies']).invoke(function(_$cookies_) {
        $cookies = _$cookies_;
    });
    

My question is if there way to get the translation table for a given language so that I can put it into a cookie. I've dug through the source code for the module a bit, and the only thing that I have found is only a local function and is not exposed for my use.

Any comments and suggestions on my approach to solving this problem are also welcome.


Solution

  • I decided to fix this in a much more elegant way. Instead of using the useUrlLoader function, I used a custom loader.

    $translateProvider.useLoader("translationFactory");

    myApp.factory("translationFactory", function($q, $resource, localStorageService) {
        var GetTranslationsResource = $resource(baseHref + 'url/to/my/load/actiongetTranslations.do', {}, {});
    
        return function(options) {
            var deferred = $q.defer();
    
            var currentTime = new Date().getTime();
            var twelveHours = 12 * 60 * 60 * 1000;
    
            var translationStorage = localStorageService.get("translationStorage");
            if(translationStorage && translationStorage.expiration + twelveHours > currentTime && translationStorage.translations[options.key]) { // Have local storage, it hasn't been 12 hours yet, and we have translations for this language
                setTimeout(function() { // Need a timeout so that the promise returns first
                    return deferred.resolve(translationStorage.translations[options.key]);
                }, 500);
            } else {
                GetTranslationsResource.get({"lang" : options.key}, function(result) {
                    switch(result.status){
                        case 'success':
                            var newTranslationStorage = {
                                expiration : currentTime,
                                translations : {}
                            };
                            newTranslationStorage.translations[options.key] = result.data;
                            localStorageService.set("translationStorage", newTranslationStorage);
                            return deferred.resolve(result.data);
                            break;
                        case 'error': deferred.reject(options.key); break;
                        case 'logout': hideLoader(); ajaxLogout(); break;
                    }
                }, function(){
                    return deferred.reject(options.key);
                });
            }
    
            return deferred.promise;
        };
    });