javascript - Angular Translate async timing issue with $translateProvider.useStaticFilesLoader -


i using excellent angular translate ($translate) directive/service deal multiple locale languages , since have multiple locale files use convenient $translateprovider.usestaticfilesloader load translation files through structure of localeabbr.json, example en.json, es.json, etc... built plunker show open source project , project uses locale through git raw files (pointing actual github repository, meaning not local plunker demo). project built directive , service, made small plunker show timing issue json file loading.

all seems $translateprovider.usestaticfilesloader works asynchronous while need synchronous because time plunker runs, json files not yet parsed while called $translate.instant() on messages.

i have plunker showing problem.

and here part of quick service demo:

app.factory('validationservice', ['$filter', '$translate', function ($filter, $translate) {   var service = this;   var validationsummary = [];   var errormessages = [     'invalid_alpha',     'invalid_alpha_space',     'invalid_alpha_num',     'invalid_boolean'   ];    //var $translate = $filter('translate');    for(var i=0, ln=errormessages.length; < ln; i++) {     validationsummary.push({         field: i,       message: $translate.instant(errormessages[i])     });   }    // attach public functions   service.getvalidationsummary = getvalidationsummary;   return service;    // function declaration   function getvalidationsummary() {     return validationsummary;   } }]); 

the $translateprovider configuration

app.config(['$translateprovider', function ($translateprovider) {   $translateprovider.usestaticfilesloader({     prefix: 'https://rawgit.com/ghiscoding/angular-validation/master/locales/validation/',     suffix: '.json'     });      // load english ('en') table on startup     $translateprovider.preferredlanguage('en').fallbacklanguage('en'); }]); 

call service through controller:

app.controller("testcontroller", function($scope, validationservice) {   var vm = this;   vm.displayvalidationsummary = true;    vm.validationsummary = validationservice.getvalidationsummary(); }); 

and html using controller:

<div class="alert alert-danger alert-dismissable" ng-show="vm.displayvalidationsummary">   <button type="button" class="close" data-dismiss="alert" aria-hidden="true" ng-click="displayvalidationsummary = false">&times;</button>   <h4><strong>{{ 'errors' | translate }}!</strong></h4>   <ul>       <li ng-repeat="item in vm.validationsummary">{{item.field }}: {{item.message}}</li>   </ul> </div> 

since i'm using angularjs 1.3+, found $translate gets translated once, author suggest use translatefilter.$stateful = true; , tried doesn't seem help.

again here plunker

i have been spending weeks on trying find , code kind of solution never got work , i'm sad of seeing raw translation code :(

please help!!!

edit
realized question not covering related problem. on top of translation delay problem, have pass arguments , huge problem passing them translation anonymous function. time promise finished, state of arguments have changed. example:

$translate(validator.message).then(function(translation) {     // log invalid message in $validationsummary     addtovalidationsummary(formelmobj, translation);      // error display     if(!isvalid) {       updateerrormsg(translation, isvalid);     }else if(!!formelmobj && formelmobj.isvalid) {       addtovalidationsummary(formelmobj, '');     } }, function(data) {     throw 'failed translate' + data; }); 

when working angularjs, or javascript matter need embrace asynchronous paradigm. in order make dealing asynchronous code less cumbersome can employ use of promises. angular gives service called $q heavy lifting you

https://docs.angularjs.org/api/ng/service/$q

getting ones head around promises can take time worth effort in long run.

essentially need validationservice make use of $translate's promise api give translation require based on supplied key when in position so. boils down ask $translate of translationid's wish translation , when have been fetched populate validationsummary array messages.

app.factory('validationservice', ['$q', '$translate', function ($q, $translate) {    var translationspromises = [],      validationsummary = [],     errormessages = [       'invalid_alpha',       'invalid_alpha_space',       'invalid_alpha_num',       'invalid_boolean'     ];     angular.foreach(errormessages, function(val, key) {     translationspromises.push($translate(val));   });    $q.all(translationspromises)     .then(function(translations) {       angular.foreach(translations, function(val, key) {         validationsummary.push({           filed: key,           message: val         });       });     })     .catch(function (err) {       console.error('failed translate error messages validation summary', err);       });    // function declaration   function getvalidationsummary() {     return validationsummary;   }    return {     getvalidationsummary: getvalidationsummary   };  }]); 

i've forked plunker , modified include above sample

http://plnkr.co/edit/7dcwvy9jloxwfetktcda?p=preview

another observation using translate filter in html. please aware can prove expensive if have large dom angular make call translate each key on every digest. approach consider provide vm labels object , use $filter service populate them upon controller instantiation.


Popular posts from this blog