Reputation: 12321
I have this little sample of a select-box that is generated by the content of a Map.
https://stackblitz.com/edit/angular-mqccjn
Class
public map : Map <string, string> = new Map <string, string> ([
[ "NEW", "?" ],
[ "ACCEPTED", "✓" ],
[ "DECLINED", "✕" ]
]);
Component
<select>
<option *ngFor="let m of map.keys()" [innerHTML]="map.get(m)"></option>
</select>
I do not know why I get this Java Runtime Exception.
ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'ngForOf: [object Map Iterator]'. Current value: 'ngForOf: [object Map Iterator]'."
Upvotes: 0
Views: 348
Reputation: 71891
It will re-evaluate the map.keys()
on every cycle, causing it to get a new object every time. You better store this immediately somewhere like this:
public map : Map <string, string> = new Map <string, string> ([
[ "NEW", "?" ],
[ "ACCEPTED", "✓" ],
[ "DECLINED", "✕" ]
]);
public mapEntries = Array.from(this.map.entries());
and your template:
<select>
<option *ngFor="let m of mapEntries" [value]="m[0]">{{m[1]}}</option>
</select>
Another way is to keep it like you had, and use the OnPush
change detection strategy, which is anyways recommended for performance reasons:
import { Component, ChangeDetectionStrategy } from '@angular/core';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class AppComponent {}
Upvotes: 2