Reputation: 234
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
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
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.
Upvotes: 4
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
Reputation: 27303
Try this:
this.form = new FormGroup({
test: new FormControl('',{updateOn:'submit'})
})
Upvotes: 2
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