Andre
Andre

Reputation: 893

How to show translations using Angular-Translate?

Angular-translate in combination with partial-loader only shows the key and not the actual translation. I've tried everything but can't seem to locate the mistake. No errors are logged.

This is my code:

app.js

var app = angular.module('myapp', [
  'ngRoute',
  'appRoutes', 
  'pascalprecht.translate',
  'angularTranslate',
  'HomeCtrl'
]); 

angular.module('angularTranslate', ['pascalprecht.translate'])
  .config(function($translateProvider, $translatePartialLoaderProvider ) {
    $translateProvider.useLoader('$translatePartialLoader', {
      urlTemplate: '/languages/{lang}/{part}.json'
    });

  $translateProvider.preferredLanguage('nl');

});

So the templates are loaded from /languages/{lang}/{part}.json

HomeCtrl.js

angular.module('HomeCtrl', []).controller('HomeController', 
  function($scope, $translate, $translatePartialLoader) {

    $translatePartialLoader.addPart('home');
    $translate.refresh();

});

In Express I have this route to ensure that the files are actually returned instead of routed to Angular:

app.get('/languages/:lang/:part', function(req, res) {
 res.sendFile(req.params.lang + '/' + req.params.part, { root: '././languages' });
});

home.json

{
    "HOMETITLE" : "Geweldige Whatsapp gesprekken.",
}

home.html

{{ "HOMETITLE" || translate }}

And finally I have linked everything in index.html using this order:

<script src="../libs/angular/angular.js"></script>
<script src="../libs/angular-route/angular-route.js"></script>
<script src="../libs/angular-resource/angular-resource.js"></script>
<script src="../libs/angular-translate/angular-translate.js"></script>
<script src="../libs/angular-translate-loader-partial/angular-translate-loader-partial.js"></script>

<script src="../js/controllers/HomeCtrl.js"></script>
<script src="../js/appRoutes.js"></script>
<script src="../js/index.js"></script>

So to restate my problem: only HOMETITLE is displayed instead of the correct translation. Any help is greatly appreciated!

Upvotes: 23

Views: 13013

Answers (3)

James
James

Reputation: 1514

From my experience with angular translate a few different issues could be happening here which is hard to pin down because your environment plays a factor into this, if you had a github repo I could clone I could be certain.

  1. You just have a formatting problem on your translate like one of the other people have stated, {{ "HOMETITLE" | translate }} You can see here for other possible ways of formatting the translation. I have run into issues using the filter translation with partial and external file loading, I would strongly recommend if you are going to be using partial loading then you only use attributes for setting your translations such as

    http://angular-translate.github.io/docs/#/guide/05_using-translate-directive

  2. Your partial file loader is running into a race condition and it is resolving the {{ "HOMETITLE" | translate }} before you actually get the translations back. Since you can use default translations with partial loading I would suggest putting in a default translation in your translate provider config to make sure that is not the case. Something as simple as what some of the other users have described as

    $translateProvider.translations('nl', {
      "HOMETITLE" : "Geweldige Whatsapp gesprekken.",
    });
    
    $translateProvider.preferredLanguage('nl');
    $translateProvider.forceAsyncReload(true);
    

Adding translateProvider.forceAsyncReload(true); to the end of the config will force a refresh. However I would recommend that you make the translation slightly different then the json file so you can see if that is the case before adding the force reload.

Upvotes: 6

Igwe Kalu
Igwe Kalu

Reputation: 14868

The issue is due to a mixup between a JavaScript language construct and an AngularJS template string interpolate expression.

Consider the following JavaScript expression:

var foo = bar || baz;

Depending on the value of bar, the expression bar || baz will return either bar or baz. When bar is truthy, it will be returned; otherwise (when it's falsy) baz will be returned.

Given the following AngularJS interpolate expression: {{ "HOMETITLE" || translate }}, the expression evaluates to the value "HOMETITLE", since that string literal is truthy.

However, the translate filter should be bound to your HTML template as follows {{ "HOMETITLE" | translate }}. Hence, the translate filter will be passed the key 'HOMETITLE' as an argument and it should return the required text.

Upvotes: 1

mpromonet
mpromonet

Reputation: 11942

As described in the angular-translate documentation you should replace || with | in the html file :

{{ "HOMETITLE" | translate }}

Hereafter a standalone snippet including the json translations :

var app = angular.module('myapp', [
  'pascalprecht.translate',
  'angularTranslate',
]); 

angular.module('angularTranslate', ['pascalprecht.translate'])
  .config(function($translateProvider, $translatePartialLoaderProvider ) {
    $translateProvider.translations('nl', {
      "HOMETITLE" : "Geweldige Whatsapp gesprekken.",
    });
    $translateProvider.preferredLanguage('nl');
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.3/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-translate/2.7.2/angular-translate.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-translate-loader-partial/2.7.2/angular-translate-loader-partial.min.js"></script>
<html ng-app="myapp">
<body>
{{ "HOMETITLE" | translate }}
</body>
</html>

Upvotes: 14

Related Questions