5

I need to create instances of multiple components dynamically on the run.

I found several examples on the internet, including StackOverflow and angular.io page itself.

But always receiving exception ExpressionChangedAfterItHasBeenCheckedError when I'm assigning a value to the component model.

Even the dedicated example for this functionality throws the same exception: Angular.io article Plunker

ERROR Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'undefined'. Current value: 'Bombasto'. It seems like the view has been created after its parent and its children have been dirty checked. Has it been created in a change detection hook ?

Should I just ignore this or it can/should be fixed?

Václav Mikeska
  • 497
  • 4
  • 9
  • this is newbie error :). don't change the state of the component manually after it was already *checked*. See http://stackoverflow.com/q/34364880/573032 – Roman C May 11 '17 at 14:22
  • thx guys, will have a look on it. Rusev solved the actual bug – Václav Mikeska May 11 '17 at 14:48
  • [Everything you need to know about the `ExpressionChangedAfterItHasBeenCheckedError` error](https://medium.com/@maximus.koretskyi/everything-you-need-to-know-about-the-expressionchangedafterithasbeencheckederror-error-e3fd9ce7dbb4) explains this behavior in great details – Max Koretskyi Jul 02 '17 at 05:24

2 Answers2

10

This is because you are altering component state in ngAfterViewInit. See the issue here discussing the behavior.

In your case you can move the initial creating in ngOnInit.

 ngOnInit() {
    this.loadComponent();
    this.getAds();
 }

https://plnkr.co/edit/vAbkBIqrhpuuWadO4zGD?p=preview

Frederik Struck-Schøning
  • 12,981
  • 8
  • 59
  • 68
rusev
  • 1,880
  • 2
  • 17
  • 14
  • Many thanks, this solved issue. Didn't expected bug directly in Angular docs on such a key functionality – Václav Mikeska May 11 '17 at 14:48
  • 1
    Actually it is not a bug, but a intended behavior - very annoying one :). – rusev May 11 '17 at 14:49
  • Currently the official example about dynamic component loading contains that error https://angular.io/generated/live-examples/dynamic-component-loader/eplnkr.html - this solution applies to that as well – Matthias Herrmann Dec 31 '17 at 12:28
  • This article shows another method using async update with a microtask: https://indepth.dev/everything-you-need-to-know-about-the-expressionchangedafterithasbeencheckederror-error/ – Bart Verkoeijen Apr 03 '20 at 14:07
5

In the more general case

use

this._changeDetectionRef.detectChanges();

at the end of the method that did update to late the component state,

... not forgetting to add

private _changeDetectionRef : ChangeDetectorRef

as parameter of the constructor of the Component owning your method.

See discution here

Frederik Struck-Schøning
  • 12,981
  • 8
  • 59
  • 68
user1767316
  • 3,276
  • 3
  • 37
  • 46