David Gonzalez
David Gonzalez

Reputation: 655

Angular 2 and i18n in typescript

I saw that angular2 implements i18n for its components and that by using i18n (and all its related attributes like i18n-title, plurals etc ...) you can internationalize your html templates.

But i was wondering how can you internationalize strings that are provided by your typescript code. For example i have a popup where depending on the error that is throw by my backend i print in it a different message. That message is provided by a variable binding to my template and i did not found a way with angular2 internationalization to translate that text.

Quick example for better undestanding:

 typescript:
 errorMessage: string = '';
 private errorMapping: Map<number,String>;

 onError(error): void {
   this.errorMessage = errorMapping.get(error.code);
 }

 template:
 <pop-up>{{errorMessage}}</pop-up>

Is there a way to do it ?

If not am I the one implementing it in a bad way ? Should i do it differently ?

Thank you very much for your time and answers.

Upvotes: 4

Views: 1948

Answers (1)

Martin Bamford
Martin Bamford

Reputation: 404

This is an old question, but Angular 5 still does not provide support for this, and like the original questioner I am also trying to avoid using 3rd party libraries, my workaround was as follows...

  1. Define a service class called TranslationsService which has a public method to accept a key-value Map of translations, and another public method to retrieve a translation for a given key.
  2. In your entry page html, ie app.component.html, add a <span> for each translation that you may wish to access programatically anywhere in your application, ie...

    <span class="translation" #error_1200 i18n="@@error_1200">A Message already exists with this Name</span>

  3. In your app.component.css, add the following so that your static list of translations as defined above is not actually shown in the browser on entry

    .translation {display: none;}

  4. Use Angular's native i18n support to define the required translations for the spans you defined above in the normal way that you would do for any translatable text in any html file in your application.

  5. In your app.component.ts you can bind to the translations that you defined in the html, get the text from them and build up a Map of translations that can be passed to your Translations service. Since this is done in the entry component, it will be then be available from any components in your application that need to access one of these translations. Code as below:

    @Component({
      selector: 'app-root',
      templateUrl: './app.component.html',
      styleUrls: ['./app.component.css']
    })
    export class AppComponent implements OnInit {
      @ViewChild('error_1200') error1200 : ElementRef;
    
      constructor(private translationsService: TranslationsService) { }
    
      ngOnInit() {
        let translations = new Map<string, string>();
        translations.set('error_1200', 
            this.error1200.nativeElement.textContent);
        this.translationsService.setTranslations(translations);
      }
    }
    
  6. Whichever components in your app require one of these translations, just inject your Translations service and use it to retrieve what you need using the appropriate key

Upvotes: 1

Related Questions