3

I would like to use dynamic translations inside a ngFor-Loop in template like this:

<mat-card *ngFor="let user of usersList">
    <mat-card-title>
        <span>{{user.name}}</span>
    </mat-card-title>
    <mat-card-content>
        <!--This is the enum i would like to translate dynamic -->
        <span i18n="Role@@role">{{user.role}}</span>
    </mat-card-content>
</mat-card>

Is there a way with the current on-board tools of angular 5 i18e (internationalization) to dynamically translate this enum value?

As I read, in Angular 6.1 or later there will be a way to translate values in .ts. But what, if i would like to use this for now? Any workarounds?

To use alternative text messages could't be a good way, because what if you habe hundred of values in the enum. I would'n repeat my enum in the html code.

5
  • Can you use a select ICU expression ? angular.io/guide/i18n#select-among-alternative-text-messages Commented Apr 4, 2018 at 8:21
  • @David: What, if you have hundred of different values in your enum to translate? I think it could't be a solution to do it with alternative text messages. The code would be very long and unreadable... Commented Apr 4, 2018 at 9:08
  • But if I understand correctly the documentation, that'd be in the translation file, not in the code. Commented Apr 4, 2018 at 9:20
  • @David: So, i think i don't understand your comment. Could you make an example? Commented Apr 4, 2018 at 9:32
  • See example below Commented Apr 4, 2018 at 12:23

3 Answers 3

5

I also tested with .xlf

This works now for me:

<mat-card *ngFor="let user of usersList">
    <mat-card-title>
        <span>{{user.name}}</span>
    </mat-card-title>
    <mat-card-content>
       <span i18n="@@roleKey">{user.roles, select, role {role}}</span>
    </mat-card-content>
</mat-card>

The translation part in my messeges.de.xlf is now

<trans-unit id="roleKey" datatype="html">
        <source>{VAR_SELECT, select, role {role}}</source>
        <target>{VAR_SELECT, select, SUPER_ADMIN {Super Admin} LIZENZ_MANAGER {Lizenz Manager} RECHTLICHE_EXPERT {Rechtliche-Expert} INFRASTRUKTRELLE_EXPERT {Infrastruktrelle-Expert} SPORTLICHE_EXPERT {Sportliche Expert} ADMINISTRATIVES_EXPERT {Administratives-Expert} FINANZIELLE_EXPERT {Finanzielle-Expert} LIZENZ_BEWERBER {Lizenz-Bewerber} }</target>
        <context-group purpose="location">
            <context context-type="sourcefile">app/locallogin/locallogin.component.ts</context>
            <context context-type="linenumber">18</context>
        </context-group>
</trans-unit>
Sign up to request clarification or add additional context in comments.

1 Comment

what if I want to do similar to this but to generate a set of chkboxes that from an JSON array? Not from ENUM buttons = [ { "displayName": "Approved", "isActive": true, "id": "order-approved" }, { "displayName": "Shiped", "isActive": true, "id": "order-shiped" } ] I want to translate the displayName property?
3

I managed to make it work. Here is my example using format xlif2 with a select ICU expression

https://angular.io/guide/i18n#translate-select

Here is how I translated the select

component.html

    <ul>
      <li *ngFor="let user of users">
        <span i18n="@@role">dummy {user.role, select, admin {admin}}</span>
      </li>
      </ul>

Note:

  • I needed to add some text before the ICU expression (dummy) otherwise it did not work.
  • Assign an id to the translation (here it's role)
  • You do not need to have all possible values defined here . For instance, I just defined one (admin) to have a valid ICU expression. All other possible values will just be in the translation files

Then extract the message file (e.g. for french)

    ng xi18n --outputPath src/locale --locale fr--i18nFormat=xlf2 --outFile messages.fr.xlf

Then set the translations in the message messages.[language].xlf file

    <unit id="role">
      <segment>
        <source>ROLE <ph id="0" equiv="ICU" disp="{user.role, select, admin {...} user {...} other {...}}"/></source>
        <target>ROLE <ph id="0" equiv="ICU" disp="{user.role, select, admin {...} user {...} other {...}}"/></target>
      </segment>
    </unit>
    <unit id="7222321253551421654">
      <segment>
        <source>{VAR_SELECT, select, admin {administrator} user {user} other {other} }</source>
        <target>{VAR_SELECT, select, admin {administrateur} user {utilisateur} other {autre} }</target>
      </segment>
    </unit>

The ID of the unit 7222321253551421654 containing the actual values to translate is the one generated by the tool. You just need to modify that unit to add as many roles/translations as you want

4 Comments

Thanks for your answer. But for me this is not really a good solution. If i had for example 8 different roles i would need to "copy" all values in the enum as select option to my html code. In my example i would have something like this: <span i18n="@@roleKey">{user.roles, select, SUPER_ADMIN {SUPER_ADMIN} LIZENZ_MANAGER {LIZENZ_MANAGER} RECHTLICHE_EXPERT {RECHTLICHE_EXPERT} INFRASTRUKTRELLE_EXPERT {INFRASTRUKTRELLE_EXPERT} SPORTLICHE_EXPERT {SPORTLICHE_EXPERT} ADMINISTRATIVES_EXPERT {ADMINISTRATIVES_EXPERT} FINANZIELLE_EXPERT {FINANZIELLE_EXPERT} LIZENZ_BEWERBER {LIZENZ_BEWERBER}}</span>
No, like in my example you DON'T need to have all your values in the HTML code. In my example, there are just one value in html (admin), but 3 values in the translation files (admin, user, other)
Ok, I see! It works! All i need is something like <span i18n="@@roleKey">{user.roles, select, role {role}}</span>
Exactly. It took me a while to make it work... but I'll probably need it too anyway =)
1

The other methods listed here work great, but I prefer not to use them, as it means that you need to add another translation file in the language of your source text, or else the original source text won't display. For example, if you change:

<mat-card *ngFor="let user of usersList">
  <span>{{user}}</span>
</mat-card>

to:

<mat-card *ngFor="let user of usersList">
  <span>dummy {user.role, select, admin {admin}}</span>
</mat-card>

The span text won't display properly unless you have a translation file that contains your source text with the target translation in the original language. This just creates extra work in my view, and also makes the html code look messy.

I prefer to add the localisation tags directly to the 'users' variable, like so:

 usersList= [
      {
        name: $localize`Admin`,
      },
      {
        name: $localize`Other`,
      },
    ]

You can then generate your messages file and add the target translation below the source using the methods outlined by the other users on this post. Using this method, you can build your app normally without any localize option and it will still work.

Note that, for this method though, unike the other methods described on this post, you'd have one trans-unit per item.

Notice also that the quotation marks are ``, not ''. It will only work if you use template literals.

If you want to add custom ids, descriptions and meanings, you'd use this method:

name: $localize`:meaning|description@@customid:Admin`,

Finally, if your data is coming from the backend and you can't add the $localize tag to it, you can create a function that loops through the data in your ts component after retrieving it and adds the $localize tag to each necessary item.

I hope this helps!

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.