1

Say I have an angular filter translate which does stuff on strings – doesn’t matter what – and a filter sort which sorts stuff alphabetically (as in orderBy : 'toString()').

I now want to print out strings from an array str of strings, but sorted according to their translation. That is, I want to make the following html code work:

<div ng-repeat="s in strs | translate | sort">{{ s }}</div>

It doesn’t work – I assume it’s because translate is a filter acting on strings, sort of like having signature String → String. But I need it to act on arrays of strings, right? Sort of like having signature [String] → [String], right? If that’s true, I need to find a way to map translate over arrays, such as strs, within that angular expression.

How can I do that or achieve what I want elegantly in the angular way?

Example. Say translate sends strings 'a', 'b', 'c' to 'z', 'y', 'x' respectively. I then want the angular-enhanced html element above to produce an equivalent html output to:

<div>c</div> <div>b</div> <div>a</div>
3
  • Does putting parens make a difference? s in (strs | translate | sort) Commented Mar 11, 2016 at 17:17
  • @acbabis No, it doesn’t seem so. (But wouldn’t make much sense if it did, right?). On the other hand, there’s a rather complex example behind this question and I’m bad with fiddling. I only tested this with my complex example, and not with something simple, so I wouldn’t know for sure (because I’m not sure where the error is actually coming from). Commented Mar 11, 2016 at 17:22
  • I don't understand why your solution doesn't work (maybe it has something to do with stateless filters...), but you may be able to achieve this with a filter function : | orderBy: myFilter(), and inside your filter function just return $filter('translate')(string) Commented Mar 11, 2016 at 17:28

1 Answer 1

1

If your translation library doesn't support translation on an array, I would add a new filter to your project for this purpose:

angular.module("mymodule", ["pascalprecht.translate"]);
angular.module("mymodule").config(function($translateProvider) {
  // Set up message keys
  $translateProvider.translations('en', {
    A: 'Apple',
    B: 'Banana'
  })
}).run(function($translate) {
  // Select language
  $translate.use("en");
})
/**
 * @filter translateArray
 * @description Convert an array of message IDs 
 * to an array of translations using the `$translate` service
 * @param {Array<String>} translationIDs - An array of message keys
 * @returns {Array<String>} - An array of translated strings.
 */
.filter("translateArray", function($translate) {
  return function(translationIDs) {
    return translationIDs.map(function(id) {
      return $translate.instant(id);
    })
  };
}).controller("demoController", function($scope) {
  // Template will translate then sort. Should give:
  // Apple, Banana
  $scope.strs = ["B", "A"];
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-translate/2.10.0/angular-translate.min.js"></script>

<body ng-app="mymodule">
  <div ng-controller="demoController">
    <div ng-repeat="s in (strs | translateArray | orderBy:'toString()')">{{s}}</div>
  </div>
</body>

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.