简体   繁体   中英

ngx-translate: How to translate dynamically array of strings

I want to create list of days of the week with ngx-translate, but it's not working with async pipe. I've got error "error TS2769: No overload matches this call." I have to use JSON file.

TS:

    MON:Observable<string> = this.translate.get('CALENDAR.MON');
      TUE:Observable<string> = this.translate.get('CALENDAR.TUE');
      WED:Observable<string> = this.translate.get('CALENDAR.WED');
      THU:Observable<string> = this.translate.get('CALENDAR.THU');
      FRI:Observable<string> = this.translate.get('CALENDAR.FRI');
      SAT:Observable<string> = this.translate.get('CALENDAR.SAT');
      SUN:Observable<string> = this.translate.get('CALENDAR.SUN');
    
    
    
      daysOfWeeks:string[] = [`${this.MON}`, `${this.TUE}`, `${this.WED}`, `${this.THU}`, `${this.FRI}`, `${this.SAT}`, `${this.SUN}`];

 constructor(
      public translate: TranslateService
    ) { }

HTML:

 <div *ngFor="let day of daysOfWeeks">{{ day | async}}</div>

I also tried use pipe directly into ngFor but still doesn't work.

I'm going to share two ways of solving this problem.

1- you can use translateService.instant

instant(key: string|Array, interpolateParams?: Object): string|Object: Gets the instant translated value of a key (or an array of keys). /.\ This method is synchronous and the default file loader is asynchronous. You are responsible for knowing when your translations have been loaded and it is safe to use this method. If you are not sure then you should use the get method instead.

like this

//for single
    const traslateSingle :string =  this.translateService.instant("Monday"); // translated "Monday"

//for list
    const transaletedList = ["Monday", "Tuesday", "Wednesday"].map(x=> this.translateService.instant(x)) // translated Week days

But it has its own issues what if translation has not been loaded? what if language selection has changed, now its ur responsibility to get updated translations

2- use translate pipe in component.html

const daysOfWeeks = ["Monday", "Tuesday", "Wednesday"]
 <div *ngFor="let day of daysOfWeeks">{{ day | translate}}</div>

it take the responsibility and automatically translate text and detection language change and then translating again.

so its kind a better solution for your problem.

TL;DR

There is also a possibility to use indexed reference. Consider that you have 2 different language as English and Turkish;

en.json

{
  ...
  "months": ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]
}

tr.json

{
  ...
  "months": ["Ocak", "Şubat", "Mart", "Nisan", "Mayıs", "Haziran", "Temmuz", "Ağustos", "Eylül", "Ekim", "Kasım", "Aralık"]
}

apply through those array definitions over translate instant output:

getMonths(months: string[]): string[] {
    return months.map((_, i) => this.translateService.instant(`months.${i}`));
}

finally, it gives the result of new array which is translated for every item of it by calling the method, getMonths

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM