I know there are a lot of same questions already posted in stack-overflow and tried different solutions to avoid the run-time error but None of them are working for me.
Component and Html Code
export class TestComponent implements OnInit, AfterContentChecked { @Input() DataContext: any; @Input() Position: any; sampleViewModel: ISampleViewModel = { DataContext: : null, Position: null }; constructor(private validationService: IValidationService, private modalService: NgbModal, private cdRef: ChangeDetectorRef) { } ngOnInit() { } ngAfterContentChecked() { debugger; this.sampleViewModel.DataContext = this.DataContext; this.sampleViewModel.Position = this.Position; } <div class="container-fluid sample-wrapper text-center" [ngClass]="sampleViewModel.DataContext?.Style?.CustomCssClass +' samplewidget-'+ sampleViewModel.Position?.Columns + 'x' + sampleViewModel.Position?.Rows"> //some other html here </div>
Please Note : This Component is loaded dynamically using DynamicComponentLoader
After My trouble shooting I have identified couple of issues
First of all this child component is loaded dynamically by using DynamicComponentResolver and passing the input values like below
ngAfterViewInit() { this.renderWidgetInsideWidgetContainer(); } renderWidgetInsideWidgetContainer() { let component = this.storeFactory.getWidgetComponent(this.dataSource.ComponentName); let componentFactory = this._componentFactoryResolver.resolveComponentFactory(component); let viewContainerRef = this.widgetHost.viewContainerRef; viewContainerRef.clear(); let componentRef = viewContainerRef.createComponent(componentFactory); debugger; (<IDataBind>componentRef.instance).WidgetDataContext = this.dataSource.DataContext; (<IDataBind>componentRef.instance).WidgetPosition = this.dataSource.Position; }
Even If I changed my child component html like below I am getting this same error.Just add a angular ngclass attribute
<div class="container-fluid ds-iconwidget-wrapper text-center" [ngClass]="Sample"> </div>
My databinding and everything are working fine.Do I need to do anything on parent component? I already tried all the lifecyle events in child component
Navigate up the call stack until you find a template expression where the value displayed in the error has changed. Ensure that there are no changes to the bindings in the template after change detection is run. This often means refactoring to use the correct component lifecycle hook for your use case.
ngAfterViewInit() is called after all child components are initialized and checked. In the example above, ngAfterViewInit() gets called one time after ngDoCheck. Triggering the clickMe() function WILL NOT trigger ngAfterViewInit().
you have to tell angular
that you updated the content after ngAfterContentChecked
you can import ChangeDetectorRef
from @angular/core
and call detectChanges
import {ChangeDetectorRef } from '@angular/core'; constructor( private cdref: ChangeDetectorRef ) {} ngAfterContentChecked() { this.sampleViewModel.DataContext = this.DataContext; this.sampleViewModel.Position = this.Position; this.cdref.detectChanges(); }
The ngAfterContentChecked
lifecycle hook is triggered when bindings updates for the child components/directives have been already been finished. But you're updating the property that is used as a binding input for the ngClass
directive. That is the problem. When Angular runs validation stage it detects that there's a pending update to the properties and throws the error.
To understand the error better, read these two articles:
ExpressionChangedAfterItHasBeenCheckedError
errorThink about why you need to change the property in the ngAfterViewInit
lifecycle hook. Any other lifecycle that is triggered before ngAfterViewInit/Checked
will work, for example ngOnInit
or ngDoCheck
or ngAfterContentChecked
.
So to fix it move renderWidgetInsideWidgetContainer
to the ngOnInit()
lifecycle hook.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With