1

We're using angular translate to handle localization of a web site, using our own custom loader that fetches translations from the server. On the server side, we have logic that handles missing translation keys so that we both return something (a translation from a fallback language or the key itself) and reports to the system that the key was requested (so it shows up in the translation UI elsewhere on the site). Now, I'm struggling with building something similar on the client side.

The $translateProvider has a method useMissingTranslationHandler(factory) which we've successfully configured to just log out that a key is missing to the console, using the following:

app.config(function ($translateProvider) {
    $translateProvider.useMissingTranslationHandler('translationMissingHandler');
});

app.factory('translationMissingHandler', translationMissingHandler);

translationMissingHandler.$inject = ['$window', '$log', '$http'];
function translationMissingHandler($window, $log, $http) {
    return function (translationId) {
        var culture = $window.preferredCulture, // workaround for another problem
            errorInfo = {
                key: translationId,
                culture: culture
            };
        $log.warning('Translation missing:', errorInfo);
        // $http.post('/api/v2/localization/missing', errorInfo);
    }
}

However, then I uncomment the POST to the server, notifying about the missing key, the page hangs on line 14394 of angular.js - throw e, where e.message is

[$rootScope:infdig] 10 $digest() iterations reached. Aborting! Watchers fired in the last 5 iterations: []

I've tried various things to get around this - e.g. wrapping the call to $http.post() in $timeout or $rootScope.$apply but to no avail; I still get the same error message.

Is there a way to schedule a call to $http.post() from here without causing this error? If so, how?

Tomas Aschan
  • 58,548
  • 56
  • 243
  • 402
  • It looks like `missingTranslationHandler` cannot be used asynchronously - [it expects the result right away](https://github.com/angular-translate/angular-translate/blob/133463ab279b6852f1f5190c43e12b6dcefe41f4/src/service/translate.js#L1160) – New Dev Feb 16 '15 at 09:19
  • @NewDev: I'm totally OK with not doing anything with the result of the `$http` call - basically, just queue the call and continue (which is what I thought the promise API stuff was supposed to do anyway). What surprises me is that I don't seem to be able to even queue an asynchronous call from the handler, regardless if I want to wait for it to complete. – Tomas Aschan Feb 16 '15 at 09:29
  • What do you mean by "queue"? The library expects the function to return a string, which is a result of a translation, and it doesn't seem to handle a promise as a return value. There is not much you could do here, it seems. – New Dev Feb 16 '15 at 09:37
  • @NewDev: As far as I can tell, I'm not returning anything either with or without the $http call. By "queue", I simply mean starting an asynchronous task, without (anywhere!) waiting for it to complete. – Tomas Aschan Feb 16 '15 at 09:39
  • 1
    Oh, I see - you are just trying to log the result. Well, I've found that if you have a watched expression in Angular, like `{{doSomething()}}`, and you invoike `$http` there, then it causes the same error (try that in a plunker - it will hang that browser tab) – New Dev Feb 16 '15 at 10:03
  • What happens if you switch between the 2 statements? first do $http and then $log (I know this sounds stupid but worth trying). if that doesn't help, how about using $timeout to wrap the $http call? – guy mograbi May 30 '15 at 07:55

0 Answers0