I have implemented a mat-select form element linked to a FormControl for validation purposes. The desired outcome is to display an error message below the element if the select box is left empty or nothing is selected.
However, upon submitting the form without selecting an option, it still registers as valid even though I have set it as required.
<form [formGroup]="cityForm" (submit)="submit()">
<mat-form-field>
<mat-label>Select City</mat-label>
<mat-select [(ngModel)]="city.Id"
[formControl]="cityFormControl"
[errorStateMatcher]="matcher">
<mat-option *ngFor="let c of dropdowns.Cities"
[value]="c.Id">
{{c.Name}}
</mat-option>
</mat-select>
<mat-error *ngIf="cityFormControl.hasError('required')">
City is <strong>required</strong>
</mat-error>
Controller code:
//Code snippet for Angular
import { Component, Input, OnInit } from '@angular/core';
import { FormControl, FormGroup, FormGroupDirective, NgForm, Validators } from '@angular/forms';
import { ErrorStateMatcher } from '@angular/material/core';
@Component({
...
})
export class CityComponent implements OnInit {
city: any = {};
dropdowns: any = {};
// Form Control Variables
matcher = new MyErrorStateMatcher();
cityFormControl = new FormControl('', [Validators.required]);
cityForm = new FormGroup({
city: this.cityFormControl
});
constructor() {
}
ngOnInit(): void {
this.dropdowns = [
{Id: 1, Name: "Toronto"},
{Id: 2, Name: "Chicago"}
];
}
submit(form : FormGroup): void {
if (form.valid == false) {
//doesn't get called
return;
}
return;
}
/** Custom error state matcher for handling invalid controls */
export class MyErrorStateMatcher implements ErrorStateMatcher {
isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean {
const isSubmitted = form && form.submitted;
return !!(control && control.invalid && (control.dirty || control.touched || isSubmitted));
}
}
Can anyone provide insights on why the required validation is not functioning as expected?