Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use i18n with component inputs that are objects in Angular?

There is a situation where an input is defined on a child component like the following:

interface MyValues {
   text: string;
   path: string;
   someOtherValue: string;
}

@Input() myValues: MyValues;

I need to pass myValues to the child component from the parent via an input like the following:

<my-child-component [myValues]="myValues" />

Since it's not a simple data type input, I can't use the attribute style of i18n as recommended in the Angular docs here. This is an object with multiple values so it can't be translated as it's passed to the child component (unless I'm missing something).

In the child component, there is some code such as the following:

<span *ngFor="let myValue of myValues">
   <a>{{myValue.Text}}</a>
</span>

Ordinarily what I'd like to do is assign an id to that anchor that needs translated like the following:

<a i18n="@@myChildComponent_text">{{myValue.Text}}</a>

The problem with this is it will create exactly one field in the translation file named, @@myChildComponent_text to be translated. However, this object being passed in to this child component is dynamic in what values are inside of myValues and therefore the literal translation will vary depending on what's being passed in.

My question is, how do I still leverage the i18n Angular internationalization abilities and @@id custom ids when passing an object to an input on a child component, where that object will have varying physical values within it that need translated?

like image 969
atconway Avatar asked Aug 30 '19 21:08

atconway


People also ask

How would you implement localization in Angular using i18n tools?

Open the angular. json file and add the following configuration. Here we have added the configuration for the Spanish language. We have provided the path and format for the i18n file and set the locale to "es." When we execute the application, the app content will be served from the i18n file path provided.

How do I translate words into components TS files?

component. ts file we need to import a translate service from @ngx-translate/core package inject the service in constructor and use it after changing the language. Now create a folder inside assets, name it 'translate,' inside of it create a json file.


1 Answers

Dynamic fields cannot be translated using angulars i18n. Because eventually it is a simple text replace what happens.

You add an attribute to your HTML-Tags which contains simple text. The ng extract command creates a file (XLIFF 1.2 (default), XLIFF 2, XML Message Bundle (XMB)), which can be used with different tools (normally this is done by an Translator) to create a new, translated file. You can extend angular.json with a configuration for each language, telling angular which translation file should be used. For example French:

"configurations": {
...
"fr": {
  "aot": true,
  "outputPath": "dist/my-project-fr/",
  "i18nFile": "src/locale/messages.fr.xlf",
  "i18nFormat": "xlf",
  "i18nLocale": "fr",
  ...
}

When you now use ng-build --configuration=frAngular replaces your static text with the one from the translation file. For every language a separate application is built. When you deploy your app you handle different languages using different urls, e.g. host/my-app/fr for French or host/my-app/de for german, each pointing to a specific translated build of your application.

The downside of this approach is you cannot handle dynamic values because it works only with static text. That's why you have to use a third party library for handling this scenario. A common library would be ngx-translate. Where you can resolve ids against a json file. If you want to use multiple translation files you can also use ngx-translate-multi-http-loader in combination with ngx-translate.

Mostly you combine i18n with ngx-translate (or another similar library) to get full multi language support.

EDIT 05.02.2021:

The future of ngx-translate is unclear, PRs will be merged it is currently kind of a basic support. More Information here: https://github.com/ngx-translate/core/issues/783

As an alternative try out:

ngneat/transloco

like image 103
J. S. Avatar answered Sep 18 '22 04:09

J. S.