UPDATE Jenson-button-event find a better option, see the SO answer
Looking into your code, I see that you use Angular Material to create your custom FormControl. Well, The problem when use Angular material is how make that the "errors" appears.
When we use <mat-error>
the error appears if the control is invalid. Take account that is invalid our custom form conrol, NOT the input-material. How avoid this inconvenience?
The solution is using a CustomFieldErrorMatcher. if we can create a CustomFiledErrorMatcher that take account the errors of our customFormControl, we can do some like
class CustomFieldErrorMatcher implements ErrorStateMatcher {
constructor(private customControl: FormControl) { }
isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean {
return control.dirty && this.customControl.invalid;
}
}
Well, it's only in ngAfterView write some like
ngAfterViewInit(): void {
const ngControl: NgControl = this.injector.get(NgControl, null);
if (ngControl) {
setTimeout(() => {
this.control = ngControl.control as FormControl;
})
}
}
Has a function
errorMatcher() {
return new CustomFieldErrorMatcher(this.control)
}
And create our custom-formControl.html like
<mat-form-field>
<mat-select [ngModel]="value" (ngModelChange)="value=$event;onChange($event)"
[placeholder]="placeholder" [disabled]="disabled"
[errorStateMatcher]="errorMatcher()">
<mat-option *ngFor="let option of optionList" [value]="option.value">
{{ option.label }}
</mat-option>
</mat-select>
<mat-error *ngIf="control?.hasError('required')">Required</mat-error>
<mat-error *ngIf="control?.hasError('error')">{{control?.errors.error}}</mat-error>
</mat-form-field>
You can see in the stackblitz two forms, one that use a customFormControl, and another one in clasic mode
(selectionChange)="onChange($event.value)"
– Eliseo