I have this custom input component, using ControlValueAccessor and it is perfectly in sync with the controlling formGroup, and gives the valid, invalid, touched and hasErrors('required') to the formGroup & internally correctly.
Whenever i want to use the mat-error component, it will only work as expected when I give the required attribute to the input. When I leave that out, the mat-error will _never_ show, whatever I try. So on blur (touched=true) it will not show the mat-error. But it _does_ in this simple plunkr: https://plnkr.co/edit/cJFCUITMlcBc78v06937?p=preview
I'm not sure why this is, the only thing I can think of is that I use [(ngModel)]="_value" on the input i.c.w. NG_VALUE_ACCESSOR/ControlValueAccessor, but I would think that since the formGroup state is correct, and it all works perfectly when having the required property on it, this should be irrelevant.
Looking at this @crisbeto's answer: https://github.com/angular/material2/issues/4027 Point 1 seems to be saying a similar thing, that setting required on it, it works, and towards the end @willshowell states Errors are hidden until the input is both invalid and touched yet they are both invalid and when touched still don't show it.
I would expect the required to not be relevant to showing the mat-error element. For example, I might want to validate an email with Validators.email but have it optional.
This plunkr demonstrates it by simply clicking and blurring each input field: https://plnkr.co/edit/4B2OOc5Spv9ewxbeIndZ?p=preview
Although While recreating it in plunkr, I found out some new strange behaviour. The first instance of the component doesn't seem to apply the placeholder attribute, and also doesn't change the touched state; however this problem has not occurred on my project (yet). See: https://plnkr.co/edit/FODeH4ZhE7IG01dmYCiR?p=preview This does indicate something strange going on, and I cannot figure out what it is.
I would expect required not to be required for mat-error to work.
mat-error.mat-error like: <mat-error error>{{ getError() }}</mat-error> and then <ng-content select="[error]"></ng-content> But then it is placed wrongly and will always show the error, probably would not fix this issue either.Injector & NgControl and subscribing to statusChanges and could see the internal status is correct as well.Maybe I am misunderstanding your issue, but is it not simply that the mat-error in ui-autocomplete.html is binding to your input (the one with [(ngModel)]="_value", which is itself only invalid if it has the required attribute? An empty value for this input will be valid otherwise, and no error will be shown.
@benelliott No, the formControl.valid property is false (or .invalid is true) whether it's required or not, So in either cases it should show. Take for example the same but with email: https://plnkr.co/edit/DxCg9mn40130yY6KNH3R?p=preview
Although I now see that that is not behaving as expected, and will only show the error when the field is empty, and required set. When I type in an incorrect email, it will still not show the error, whether I set required or not...
So now my question really becomes, How do I make the mat-error component show, when there is an error, and there is, but it's just now working correctly.
I think it must also be something with the implementation of this component, because The first instance will each time not show the placeholder property, and the options are somehow empty.
@mxchange What I mean is that the mat-error in ui-autocomplete.html will respond _only_ to the validity of the search input (the one it is a sibling of in a mat-form-field). It is bound to this element and not to your outer component. Thus it will only show when the search input has an error. The search input only has an error when empty if it is marked as required.
The "works without required" example you provided actually _does_ have the required validator active, but it is active in the controller rather than the template because it is an example of reactive rather than template-driven forms. Note the formControlName="email" in the template which links the input to email: ['', [Validators.required] ] in the controller, which had the required validator enabled.
@mxchange is this still an issue or were you able to resolve it?
updated plunker: https://plnkr.co/edit/zMrtVVmxi7O9Aej4gLl1?p=preview
@mmalerba not really, can you explain why the first input field is not showing the error, while it has the same required properties as the second one (in your updated plunker). And why the placeholder is not working? (It shows the default, as if it's not passing the variable...)
@mmalerba
When I use markAsTouched() to trigger the 'custom form field control', the mat-error doesn't show up.
The status is still on mat-hint.
I need to use mouse to click the 'custom form field control' for the mat-error. And I read the source code.

Maybe the problem is on this ngSwitch, could you help me to check this out?
Thank you very much.
@mxchange Does this issue resolved for you?
@divyameher no
@mxchange Did you read my comment above? Is there something I misunderstood about your use case?
I have the same issue with a custom form field...the error won't show
I solved by updating the errorState on the custom MatFormFieldControl.
Since my custom field is a formGroup made of 2 inputs I had to manually set the touched
setTouched(): void {
this.parts.markAsTouched();
this.validate(this.parts);
//Updates errorState to show mat-error
this.errorState = this.parts.invalid;
//Emit stateChange to update value in mat-form-field
this.stateChanges.next();
}
I call this function when either input is focused
EDIT
There was also a problem with the reset and errors won't be reset.
To solve, call yourFormControlOrGroup.reset() as first in the write method
writeValue(value: UbiTime): void {
this.parts.reset();
let newValue = {hours: "", minutes: ""};
if (!!value && value instanceof UbiTime) {
newValue = value;
}
this.parts.setValue(newValue);
this._handlePropagation();
}
@tonysamperi So does your Custom form field is only compatible with FormGroup or will it also works with NgModel?
@divyameher Works perfectly also with NgModel!
@tonysamperi could you show a working example of your workaround? Sorry I get confused with some part of your code but my custom form field control also consists of inputs (3 inputs)
@nhducseuit sorry, but I really can't prepare it right now...
I have to close some activities since I'll be on holiday in a couple days...
If you prepare a stackblitz maybe I can take a look...
Any updates on this?
No mat error shows if the field is not required but is invalid
Most helpful comment
I solved by updating the
errorStateon the custom MatFormFieldControl.Since my custom field is a
formGroupmade of 2 inputs I had to manually set thetouchedI call this function when either input is focused
EDIT
There was also a problem with the reset and errors won't be reset.
To solve, call
yourFormControlOrGroup.reset()as first in thewritemethod