form-field: support swapping various child components with ngIf
See original GitHub issueBug, feature request, or proposal:
I recently ran into a bug that mat-hint
threw an error when its corresponding matInput
is inserted conditionally. E.g. take the following template:
<mat-form-field>
<input *ngIf="isFile()" matInput placeholder="Enter file name" formControlName="filename">
<input *ngIf="isDirectory()" matInput placeholder="Enter directory name" formControlName="filename">
<mat-hint>
Some hint.
</mat-hint>
</mat-form-field>
Note that the only reason inputs are inserted conditionally here is because the placeholder text is different depending on the condition.
This will throw the following error:
app.component.html:7 ERROR Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'null'. Current value: 'mat-hint-0'.
at new d (VM8254 zone.min.js:1)
at viewDebugError (VM7606 core.umd.js:8466)
at expressionChangedAfterItHasBeenCheckedError (VM7606 core.umd.js:8444)
at checkBindingNoChanges (VM7606 core.umd.js:8608)
at checkNoChangesNodeDynamic (VM7606 core.umd.js:12515)
at checkNoChangesNode (VM7606 core.umd.js:12464)
at debugCheckNoChangesNode (VM7606 core.umd.js:13241)
at debugCheckRenderNodeFn (VM7606 core.umd.js:13181)
at Object.eval [as updateRenderer] (VM7993 AppComponent.ngfactory.js:78)
at Object.debugUpdateRenderer [as updateRenderer] (VM7606 core.umd.js:13163)
at checkNoChangesView (VM7606 core.umd.js:12283)
at callViewAction (VM7606 core.umd.js:12650)
at execEmbeddedViewsAction (VM7606 core.umd.js:12628)
at checkNoChangesView (VM7606 core.umd.js:12282)
at callViewAction (VM7606 core.umd.js:12650)
This is not a problem when the input is not inserted conditionally but rather placed in the template right away. I’m not sure if that is by design or not but it caused me some hours of debugging until I realised it was the combination of mat-hint
inside a mat-form-field
whom\s matInput
is rendered using *ngIf
.
What is the expected behavior?
I expected this to just work, but again, maybe this is by design but then we should document somewhere that matInput
s aren’t allowed to be inserted using structural directives.
What is the current behavior?
Described above.
What are the steps to reproduce?
Here’s a plunk that reproduces the error: http://plnkr.co/edit/MrUvFVKIW1BoX9d96eeu?p=preview
Simply check the console.
What is the use-case or motivation for changing an existing behavior?
Which versions of Angular, Material, OS, TypeScript, browsers are affected?
I’m using @angular/material
version 2.0.0-beta.11
but the plunk uses the latest version. Unfortunately I can’t tell if this error has been thrown in older versions as well.
Is there anything else we should know?
Yeah, you’re all doing an amazing job. Thanks for that.
Issue Analytics
- State:
- Created 6 years ago
- Reactions:14
- Comments:11 (1 by maintainers)
Top GitHub Comments
I am having this issue too, but it is with mat-error instead of mat-hint:
Hitting the same issue with
mat-hint
andngSwitch
:Tried switching to using
<mat-hint>
element instead to no avail:Would definitely love to see “more swappable form-field pieces” 🙏
P.S. thanks to the Angular team for the good work they’ve done so far ❤️ 👏
Update: was able to workaround by grouping the all form components together into a single conditional render – basically render the whole
mat-form-field
and its children together (not DRY but it works):