Como atribuir um array à propriedade de objeto no método Angular Subscribe?

Aug 21 2020

Estou tentando obter o valor da matriz do arquivo de tradução en.json no angular e tento vinculá-lo a uma propriedade de objeto, conforme mostrado abaixo.

código datilografado:

  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]);
                  })
    };
  };

O arquivo en.json tem a seguinte aparência:

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

Estou usando o serviço de tradutor ngx para obter os dados do arquivo en.json e, em seguida, assinar e atribuir valor à propriedade dayNamesMin do objeto this.en.

Quando eu registro o valor Object.keys (translated) .map (key => translated [key]); valor no console, estou obtendo o array correto ["SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"]. Mas não está vinculado à propriedade dayNamesMin do objeto.

Alguém pode por favor ajudar aqui?

Respostas

1 MichaelD Aug 21 2020 at 21:53

Quando você está lidando com dados assíncronos usando observáveis, é melhor atribuir valores dentro de sua assinatura em vez de confiar que a variável será atribuída quando for acessada. No seu caso, você poderia fazer algo como o seguinte

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])
      };
    });
}

Agora você tem uma ideia de que a this.envariável não tem valor atribuído até que os this.translateSvc.get()observáveis ​​emitam. Portanto, você precisa se lembrar que this.ené assíncrono quando é acessado.

Mais informações sobre dados assíncronos aqui .


Ou diga se você deseja usar apenas a this.envariável no modelo para exibir os valores, você pode mapear a saída this.translateSvc.get()usando o mapoperador RxJS e usar o asynctubo angular .

Controlador

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]) }))
    );
}

Modelo

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

Atualização: Use com o calendário PrimeNg

Conforme mostrado na segunda variante, use o mapoperador RxJS para transformá-lo no formato de objeto necessário e usá-lo como entrada no modelo HTML.

<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>