title: Form Control not working for Angular Material Mat-select
body: <p>I have a <a href="https://material.angular.io/components/select/overview" rel="nofollow noreferrer">mat-select</a> form element tied to a FormControl for validation. The goal is to give an error box below the element if the select box isn't filled in (or nothing is selected)</p>
  
  <p>However the form is valid when submitting with no select option is chosen, even though I have a required option for it. </p>
  
  <pre><code>&lt;form [formGroup]="cityForm" (submit)="submit()"&gt;
  
  &lt;mat-form-field&gt;
     &lt;mat-label&gt;Select City&lt;/mat-label&gt;
  
     &lt;mat-select [(ngModel)]="city.Id"
                 [formControl]="cityFormControl"
                 [errorStateMatcher]="matcher"&gt;
                  &lt;mat-option *ngFor="let c of dropdowns.Cities"
                              [value]="c.Id"&gt;
                      {{c.Name}}
                  &lt;/mat-option&gt;
     &lt;/mat-select&gt;
  
     &lt;mat-error *ngIf="cityFormControl.hasError('required')"&gt;
       City is &lt;strong&gt;required&lt;/strong&gt;
     &lt;/mat-error&gt;
  </code></pre>
  
  <p></p>
  
  <p>Controller code:</p>
  
  <pre><code>//Angular Imports
  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;  
  }
  
  /** Error when invalid control is dirty, touched, or submitted. */
  export class MyErrorStateMatcher implements ErrorStateMatcher {
      isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean {
          const isSubmitted = form &amp;&amp; form.submitted;
          return !!(control &amp;&amp; control.invalid &amp;&amp; (control.dirty || control.touched || isSubmitted));
      }
  }
  </code></pre>
  
  <p>Any idea why the required validation is not working?</p>