skip to content
Alvin Lucillo

ChangeDetectorRef's detectChanges

/ 2 min read

💻 Tech

In yesterday’s journal, I shared about the ExpressionChangedAfterItHasBeenCheckedError error when a parent’s state was changed in child component where that state was previously initialized and rendered in the parent component. It was resolved by changing a sequence.

Now, the same error can be encountered when a state used by a component in its view is changed during AfterViewInit lifecycle stage, specifically in ngAfterViewInit() hook function.

When the greetings was rendered, Angular change detection saves that state and returns to it in the second check, ensuring no unexpected changes happen because it expects a unidirectional flow of data. However, in the example below, the state was changed during AfterViewInit stage. It’s a stage where child components, if any, are rendered, and it’s after the parent is rendered as well. This means, with that stage, we shouldn’t expect any changes to state at all. But if for some reason we applied any changes, that’s the the reason Angular throws that error. If for any reason you need to modify the state, you need to manually trigger the change detection by injecting the change detector and calling detectChanges() function like so:

  • cdr = inject(ChangeDetectorRef); — declare as class-level variable
  • this.cdr.detectChanges(); — call in ngAfterViewInit()

Example component:

export class ParentComponent implements AfterViewInit {
  greetings = 'Hello';

  ngAfterViewInit(): void {
    this.greetings = 'Hi';
  }
}
<p>{{ greetings }}</p>