In my app I try to loop over a map (with *ngFor
) and display every map key in a new expansion panel and the values in the "body" of the expansion panel:
The map has strings as keys and string arrays as values. After I have filled my map I pass it into the this.showMap
. The only reason for this is that I can wait for showMap
with *ngIf="showMap"
in my HTML to make sure that all items are in the map before I show the Website to the user:
showMap: any;
ngOnInit() {
let myMap: Map<string, string[]> = new Map<string, string[]>();
myMap.set("food", ["apple", "sausage"]);
myMap.set("money", ["bitcoin", "dollar"]);
//... add more key, value pairs dynamically
this.showMap = myMap;
}
In my HTML I use an accordion
and expansion-panels
from material:
<div *ngIf="showMap">
<mat-accordion>
<mat-expansion-panel hideToggle *ngFor="let key of getKeys(showMap); index as i">
<mat-expansion-panel-header>
<mat-panel-title>
{{ key }}
</mat-panel-title>
</mat-expansion-panel-header>
<p>{{ getValues(showMap)[i] }}</p>
</mat-expansion-panel>
</mat-accordion>
</div>
and the getKeys()
and getValues()
function look like this and simply return the keys and values of the showMap
:
getKeys(myMap: Map<string, string[]>) {
let keys = Array.from(myMap.keys());
console.log("keys: ", keys);
return keys;
}
getValues(myMap: Map<string, string[]>) {
let values = Array.from(myMap.values());
console.log("values: ", values);
return values;
}
My app is running as wanted, but in the console logs I see that the functions getKeys()
and getValues()
are called multiple times. I'd expect that getKeys()
gets called once (because of the *ngFor
statement) and the getValues()
gets called twice (once for each key). But it's way more, about 10 times?:
It is not consider a good practice call a function on the template, as mentioned by @Raz Ronen, function is executed every time Angular change detection runs. And that can be too many times! I would extract the values and keys into instance variables and use them instead of calling the function directly on the template.
Check out this article about it: https://medium.com/showpad-engineering/why-you-should-never-use-function-calls-in-angular-template-expressions-e1a50f9c0496