Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Expression has changed error on Opening a Modal Popup inside a component

I have a parent component and i am passing some HTML from it to a child common component using @ViewChild().

When Child component loads up a popup. Console throws below error.

"ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'ngIf: undefined'. Current value: 'ngIf: this is description'. 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 ?"

I am using { NgbModal } from '@ng-bootstrap/ng-bootstrap';

This is the code.

Update - This parent component is called as app-parent-component in another parent html file.

Parent Component

@ViewChild('templateToLoad') templateToLoad;


constructor(private modalService: NgbModal, private ChangeDetector: ChangeDetectorRef) {
}

ngOnInit() {
    this.openPopup();
}

ngAfterViewInit() {
    this.ChangeDetector.detectChanges();
}

private openPopup() {
    const modalPrompt = this.modalService.open(CommonChildModalComponent, {windowClass: 'modal-prompt fade-in-down'});
    modalPrompt.componentInstance.title = 'Title';
    modalPrompt.componentInstance.contentTemplate = this.templateToLoad;
    modalPrompt.componentInstance.originContext = this;
    modalPrompt.componentInstance.description = 'ABC';

Parent HTML

<ng-template #templateToLoad>
  <div class="someClass">This data will be shown on Popup without any error.
  </div>
</ng-template>

CommonChildPopup Component

@Input() title?: string;
@Input() description?: string;
@Input() originContext: any;
@Input() contentTemplate?: any;

constructor(public activeModal: NgbActiveModal) {
}

ngOnInit() {
    console.log('I am here in CommonModalComponent ngOnInit');
}

CommonChildPopup HTML

<div class="modal-header">
  <h4 class="modal-title">{{title}}</h4>
</div>

<div class="modal-body pb-3" [class.dimmer]="simulateLoading">
  <p *ngIf="description">{{description}}</p>
  <ng-container *ngTemplateOutlet="contentTemplate"></ng-container>

The above console error is for this line ngIf="description". If i remove this line, same error will come for next line. Please help.

like image 764
Aakash Kumar Avatar asked Mar 15 '18 06:03

Aakash Kumar


People also ask

How do you fix expression has changed after it was checked?

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.

What is modal popup in angular?

The modal component is used to add modal windows anywhere in your angular application by using the <jw-modal> tag. Each modal instance adds itself to the modal service when it loads by calling modalService.


1 Answers

You're trying to update the property values in a lifecycle hook after they have been previously checked in the parent component.

The recommended solution is to open the modal on a button click / another user triggered event, or if you need to open it after the view is initialized you can use the setTimeout() that will skip a tick

ngAfterViewInit() { setTimeout(() => this.openPopup()); }

Working plunker : https://plnkr.co/edit/FVV7QVp620lIGJwEhN6V?p=preview

A very nice and detailed explanation about this error : https://blog.angularindepth.com/everything-you-need-to-know-about-the-expressionchangedafterithasbeencheckederror-error-e3fd9ce7dbb4

like image 97
Lucian Moldovan Avatar answered Sep 28 '22 01:09

Lucian Moldovan