Given 2 components: App
and Sub
where App
has a reactive form containing
Sub
component wrapped in a ngIf checking that the checkbox is checked[disabled]="form.invalid"
and Sub
contains a required text input.
App.onInit
defines a FormGroup containing only the checkbox.
Sub.onInit
adds to the parent form a new FormGroup (parentFormDirective is injected with viewProvider)
All inputs have their matching material directives (e.g. mat-checkbox
, mat-button
, etc...")
When the checkbox is checked, ExpressionChangedAfterItHasBeenCheckedError
is thrown.
If mat-button
on the submit button is removed, the error is not thrown.
For ExpressionChangedAfterItHasBeenCheckedError
to not be thrown.
ExpressionChangedAfterItHasBeenCheckedError
is thrown.
Sample project on github.
Created i StackBlitz, but got the following error when trying to save:
PATCH https://stackblitz.com/api/projects/angular-pc3way net::ERR_EMPTY_RESPONSE
Nesting inside parent forms reusable components that impact form-validity, is one of the fundamental features of a component-based framework. Having a material-styled button should not break this feature.
Angular
5.2.8
Material
5.2.5
OS
Windows 10
TypeScript
2.4.2
@tinayuangao if you need more information, I'm happy to provide it :)
I've been going mad for hours trying to figure out that.
I really thought I had an architecture flow because I'm building a huge form, composed of sub forms and I thought that the error was because of that and that it might reveal an architecture problem.
I spent some time trying to create a small repro and yes, same result: The error is still thrown.
Until I had the idea to remove everything from material and use basic HTML: The error was gone.
I confirm that when I remove the [disabled]="userForm.invalid"
on the button, everything works fine though.
I think that the stackblitz provided here is enough but if sharing my repro can help let me know I'll push it on Github :+1:
Github are you drunk?!
I'm not even a Material contributor so quite far to be an admin =o !
same issue when validators injected from a child component change the state of the parent component (in this case, a disabled submit button becomes enabled once the child formgroup is initialized )
I'm using a simple button though, not material specific, but landed here from google
edit:: patch and maybe some clues here https://github.com/angular/angular/issues/23657#issuecomment-426058601
@maxime1992 that's just what happens when someone is removed from the repo- github attributes the action to whoever made the most recent activity
I'm just doing a equivalent things, and I have the same issue with :
Is there anything ongoing ?
Currently I work around it with OnInit and setTimeout:
export class ExampleComponent implements OnInit {
private form: FormGroup;
private formIsValid = () => false;
ngOnInit(): void {
setTimeout(() => this.formIsValid = () => this.form.valid, 0);
}
}
<button [disabled]="!formIsValid()">Submit</button>
This workaround, doesn't involve any changes to the form fields.
I got a similar error when a matInput was focused, and it sounds like there are a few bugs with Angular Material components throwing ExpressionChangedAfterItHasBeenCheckedError during normal operations. My workaround is to ignore any ExpressionChangedAfterItHasBeenCheckedError in my global error handler since they don't affect the core functionality of the code. See angular documentation for how to globally catch any JS errors in your code: https://angular.io/api/core/ErrorHandler
Same issue.
Anything new?
I was experiencing the same issue. The workaround that was appropriate in my use case was to also check if the form was pristine before checking if its valid.
[disabled]="form.pristine || !form.valid"
That was enough to fix the ExpressionChangedAfterItHasBeenCheckedError and avoid reaching for setTimeout or worrying about capturing the error handler as others have mentioned. I haven't noticed any negative side effects yet and I like that the form cannot be submitted until a user has made changes somewhere.
[disabled]="form.pristine || !form.valid" worked for me.
@Pratik12122 @dariobraun thanks for the suggestion, this work on first load but when I change fields in form on some condition then this error comes again.
I looked into this and moved the reproduction to StackBlitz: https://stackblitz.com/edit/comp-10914?file=src%2Fapp%2Fsome-directive.directive.ts.
It looks like this is _not_ an issue with the Angular Material button, as the same issue surfaces when an arbitrary directive is set up with an input binding. See the reproduction above.
Closing as this is not something specific to Angular Material.
This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.
Read more about our automatic conversation locking policy.
_This action has been performed automatically by a bot._
Most helpful comment
I've been going mad for hours trying to figure out that.
I really thought I had an architecture flow because I'm building a huge form, composed of sub forms and I thought that the error was because of that and that it might reveal an architecture problem.
I spent some time trying to create a small repro and yes, same result: The error is still thrown.
Until I had the idea to remove everything from material and use basic HTML: The error was gone.
I confirm that when I remove the
[disabled]="userForm.invalid"
on the button, everything works fine though.I think that the stackblitz provided here is enough but if sharing my repro can help let me know I'll push it on Github :+1: