bys
bys

Reputation: 234

ExpressionChangedAfterItHasBeenCheckedError when using ReactiveForms and NgbModal

I have a reactive form and when the user presses the ESC key in an input i would like to show an "are you sure" modal before the form gets hidden.
As soon as the modal is shown i get the following exception in the console:

ERROR Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has 
changed after it was checked. Previous value: 'ng-untouched: true'. Current 
value: 'ng-untouched: false'.

Here is a stackblitz that shows the issue (focus input and press ESC)

Note: When you focus the input, blur and focus again the issue wont appear as ng-untouched wont change again.

Is there any workaround? Whats the recommended way to implement such a functionality?

Thanks in advance!

Upvotes: 6

Views: 3606

Answers (5)

Michael Sacket
Michael Sacket

Reputation: 907

Another trick is to blur the activeElement before opening the dialog. Here is an example that displays a modal dialog when new is selected.

{
  type: 'select',
  key: 'destination',
  templateOptions: {
    label: 'To Account',
    options: [...accounts],
    required: true,
    disabled: false,
  },
  hooks: {
    onInit: (field) => {
      field.form.get('destination').valueChanges.subscribe((value) => {
        if( value == 'new' ){
            (document.activeElement as any).blur();
            this.modal.open(AddAccountDialogComponent);
        }
      });
    }
  }
}

Upvotes: 1

bys
bys

Reputation: 234

I finally found a way to overcome the issue but still having the dirty flag maintained.

ng-untouched is maintained onBlur when FormControl is set to {updateOn:'change'} (the default). What you have to do is simply blur the input manually before opening the modal. When the modal is shown it will blur anyway.

Here is a stackblitz

Upvotes: 4

Sudhir Roy
Sudhir Roy

Reputation: 266

It's not the issue of keyup event rather it's an issue of custom modal which you are using. Try to remove the modal and it will work or you need to initialize it first.

Upvotes: 0

Chellappan வ
Chellappan வ

Reputation: 27303

Try this:

this.form = new FormGroup({
  test: new FormControl('',{updateOn:'submit'})
})

Upvotes: 2

Suresh Kumar Ariya
Suresh Kumar Ariya

Reputation: 9764

Try to wrap the onESC block of code inside setTimeout, which will trigger Angular Change detection using zone.js.

onEsc() {
  setTimeout(()=>{
    const modalRef = this.modalService.open(NgbdModalContent);
    modalRef.componentInstance.name = 'World';
  }, 0);
}

Upvotes: 0

Related Questions