Reputation: 3676
I have a component with the method:
public *numGen(): Iterator<number> {
for (let i = 0; i < 5; ++i)
yield i;
}
and HTML with:
<p *ngFor="let n of numGen()">{{n}}</p>
I expect this to generate:
<p>0</p>
<p>1</p>
<p>2</p>
<p>3</p>
<p>4</p>
which it does, but it also generates an error:
ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked.
Previous value: 'ngForOf: [object Generator]'. Current value: 'ngForOf: [object Generator]'.
Anyone know how to prevent the error being generated?
Upvotes: 2
Views: 254
Reputation: 71911
One way is to use the OnPush
change detection strategy. This will make sure it only checks the bindings when something inside the component has changed by @Input
, or an event emitted from the template. Which by itself has a big performance improvement, and a more logical pattern of when change detection is triggered.
@Component({
// ...
changeDetection: ChangeDetectionStrategy.OnPush
})
The reason you are seeing this error, is because your method returns a new Generator
object reference with every change detection.
Another way would be to only set the generator when something changes in your component that requires the generator to update. You could use the ngDoCheck
hook for that. Be aware that this get called quite a lot, although not as often if you use the OnPush
strategy, which I anyways strongly suggest.
export class AppComponent {
generator: Iterable<number> = this.numGen();
multiplier = 1;
ngDoCheck(): void {
this.generator = this.numGen();
}
times(): void {
this.multiplier *= 2;
}
private *numGen(): Iterable<number> {
for (let i = 0; i < 5; ++i) {
yield i * this.multiplier;
}
}
}
I do wonder, for what use case are you using the iterator/generator?
Upvotes: 2