Angular - Access values of object stored in array of objects inside template
Ideally, the property name
:
{ ..., name: [{ "pl": "Tekst po polsku" }, { "en": "Text in english" }] },
Would have the format of not an array of objects, but an object:
{ ..., name: {"pl": "Tekst po polsku", "en": "Text in english"} },
Then you could simply use in your template:
<span>{{ settingsTab.name[language] }}</span>
Which is a constant-time lookup (just getting a property in an object).
Now, if you can't change the format of name
, I'd use a method instead of those nested ng-container
s:
export class MyComponent {
...
lang(names: [any], language: string) {
return (names.find(lang => lang[language]) || {})[language]
}
...
}
And use it like:
<span>{{ lang(settingsTab.name, language) }}</span>
Of course, you can call lang
whatever you see fit.
Just notice this alternative has O(n) complexity, due to find
having to iterate the name
array. This probably won't impact the performance of you application at all, but I thought you should know. In the current format of the name
, there is no quicker way here.
Demo: https://stackblitz.com/edit/angular-c5wzbk?file=src/app/app.component.ts
Ashiv3r
Updated on June 22, 2022Comments
-
Ashiv3r about 2 years
I've got a single class as below:
export class SettingsTab { id: number; class: string; name: Object = {}; }
Also I mock it into simple array:
export const SETTINGSTABS: SettingsTab[] = [ { id: 1, class: 'classOne', name: [{ "pl": "Tekst po polsku" }, { "en": "Text in english" }] }, { id: 2, class: 'classTwo', name: [{ "pl": "Tekst po polsku" }, { "en": "Text in english" }] }, { id: 3, class: 'classThree', name: [{ "pl": "Tekst po polsku" }, { "en": "Text in english" }] } ];
Now I would like to access certain value of name object in my template depending on which language I currently use. I get info about current language from localStorage as shown below:
language = localStorage.getItem('currentLang') != null ? localStorage.getItem('currentLang').replace("'", "") : "pl";
I managed to achieve it by code listed below:
<ng-container *ngFor="let name of settingsTab.name"> <ng-container *ngFor="let key of ObjectKeys(name)"> <span *ngIf="key == language">{{ name[key] }}</span> </ng-container> </ng-container>
ObjectKeys are defined in my component as:
ObjectKeys = Object.keys;
But my question is there any easiest way to achieve what I want to do? Don't like two ng-components with *ngFor inside them. Also would like to achieve it in the most optimized way.
-
Ashiv3r over 6 yearsThaks! I can change the format of name property, so I went that way and it's working like a charm :)