2

I am trying to get array value from en.json translation file in angular and try to bind it to an object property as shown below code snippet.

typescript code:

  ngOnInit() {
    this.en = {
      dayNamesMin: this.translateSvc
                  .get(['calendar.day_names_min.Sun', 'calendar.day_names_min.Mon', 'calendar.day_names_min.Tue', 'calendar.day_names_min.Wed',
                    'calendar.day_names_min.Thu', 'calendar.day_names_min.Fri', 'calendar.day_names_min.Sat'])
                  .subscribe(translated => {
                    console.log(Object.keys(translated).map(key => translated[key]));
                    return Object.keys(translated).map(key => translated[key]);
                  })
    };
  };

en.json file looks like this:

{
    "calendar" : {
        "day_names_min": {
            "Sun": "SUN",
            "Mon": "MON",
            "Tue": "TUE",
            "Wed": "WED",
            "Thu": "THU",
            "Fri": "FRI",
            "Sat": "SAT"
        }
    }
}

I am using ngx translator service to get the data from en.json file and then subscribe and assign value to dayNamesMin property of this.en object.

When I log the value Object.keys(translated).map(key => translated[key]); value in console, I am getting the proper array ["SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"]. But it is not binding to the object property dayNamesMin.

Can someone please help here ?

1 Answer 1

1

When you're dealing with asynchronous data using observables, it's better to assign values inside it's subscription instead of trusting that the variable will be assigned when it's accessed. In your case, you could do something like the following

ngOnInit() {
  this.translateSvc.
    .get([
      'calendar.day_names_min.Sun', 
      'calendar.day_names_min.Mon', 
      'calendar.day_names_min.Tue', 
      'calendar.day_names_min.Wed',
      'calendar.day_names_min.Thu', 
      'calendar.day_names_min.Fri', 
      'calendar.day_names_min.Sat'
    ])
    .subscribe(translated => {
      this.en = {
        dayNamesMin: Object.keys(translated).map(key => translated[key])
      };
    });
}

Now you have an idea that the this.en variable isn't assigned value until the this.translateSvc.get() observables emits. So you need to remember that this.en is asynchronous when it's accessed.

More info on async data here.


Or say if you only want to use the this.en variable in the template to display the values, you could map the output from this.translateSvc.get() using RxJS map operator and use Angular async pipe.

Controller

en$: Observable<any>;

ngOnInit() {
  this.en$ = this.translateSvc.     // <-- assign the observable
    .get([
      'calendar.day_names_min.Sun', 
      'calendar.day_names_min.Mon', 
      'calendar.day_names_min.Tue', 
      'calendar.day_names_min.Wed',
      'calendar.day_names_min.Thu', 
      'calendar.day_names_min.Fri', 
      'calendar.day_names_min.Sat'
    ])
    .pipe(       // <-- transform the response here
      map(translated => ({ dayNamesMin: Object.keys(translated).map(key => translated[key]) }))
    );
}

Template

<ng-container *ngIf="(en$ | async) as en">
  {{ en.dayNamesMin | json }}
  {{ en.dayNamesMin[0] }}
  ...
  <p *ngFor="let day of en.dayNamesMin">
    {{ day }}
  </p>
</ng-container>

Update: Use with PrimeNg calendar

As shown in the second variant, use RxJS map operator to transform it to the required object format and use it as the input in the HTML template.

<ng-container *ngIf="(en$ | async) as en">
  <p-calendar 
    dateFormat="dd/mm/yy" 
    [(ngModel)]="value" 
    [locale]="en">   <!-- use `en` from the async pipe -->
  </p-calendar>
</ng-container>
Sign up to request clarification or add additional context in comments.

3 Comments

My requirement is that I am using primeng calendar component where I need to send [locale] object to primeng calendar as shown below. <p-calendar dateFormat="dd/mm/yy" [(ngModel)]="value" [locale]="en"> </p-calendar> Here I need to read the value to en object from translation file. Hope now its clear
That does not work. I am not getting any data with this change. Do you mind connecting with me to help on this? Help will be appreciated.
@shrinivasdesai: Did you try {{ en.dayNamesMin | json }} inside the <ng-container>? What was the result? It should display atleast something when the en$ observable emits. If not, the other option would be the first variant that I've showed. Either way you need to check if the this.en variable is defined before binding it. In the first variant you could something like <ng-container *ngIf="en">.... If it still doesn't work please try to create a minimal working example in Stackblitz.

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.