title: Disable submit form when form invalid Angular + Material
body: <p>Im building a form using Angular 5.1.1 /Typescript 2.4.2 + Material 5 with <a href="https://www.npmjs.com/package/@ncstate/sat-popover" rel="nofollow noreferrer">sat-popover</a> library</p>
  
  <p>Trying to disable submit button while input is invalid without success.
  am using the Material <a href="https://material.angular.io/components/input/overview#changing-when-error-messages-are-shown" rel="nofollow noreferrer">Input validation example</a></p>
  
  <p>validation works and i get an error message, but button is not disabled and form is been submitted with an empty value. i can't figure out how to use the right condition to disable the button while input is invalid.
  have tried</p>
  
  <pre><code>ng-disabled="!flagForm.valid"
  </code></pre>
  
  <p>and</p>
  
  <pre><code>ng-disabled="flagForm.$invalid"
  </code></pre>
  
  <p>when using </p>
  
  <pre><code>[disabled]="!flagForm.valid"
  </code></pre>
  
  <p>i get 'TypeError: Cannot read property 'valid' of undefined'</p>
  
  <p>none of them seem to work. what am i missing ? here is the full code.</p>
  
  <pre><code>   import { Component, Input, Optional, Host } from '@angular/core';
      import { FormControl, FormGroupDirective, NgForm, Validators} from '@angular/forms';
      import { SatPopover } from '@ncstate/sat-popover';
      import { filter } from 'rxjs/operators/filter';
      import { ErrorStateMatcher} from '@angular/material/core';
  
      /** 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));
        }
      } 
  
      @Component({
        selector: 'inline-edit',
        styleUrls: ['inline-edit.component.scss'], 
        template: `
          &lt;form (ngSubmit)="onSubmit()" name="flagForm" novalidate&gt;
            &lt;div class="mat-subheading-2"&gt;Submit Your flag&lt;/div&gt;
  
            &lt;mat-form-field&gt;
              &lt;input matInput maxLength="140" name="flag" [(ngModel)]="flag" [formControl]="flagFormControl"
                 [errorStateMatcher]="matcher"&gt;
              &lt;mat-hint align="end"&gt;{{flag?.length || 0}}/140&lt;/mat-hint&gt;
              &lt;mat-error *ngIf="flagFormControl.hasError('required')"&gt;
                Flag is &lt;strong&gt;required&lt;/strong&gt;
              &lt;/mat-error&gt;        
            &lt;/mat-form-field&gt;
  
            &lt;div class="actions"&gt;
              &lt;button mat-button type="button" color="primary" (click)="onCancel()" class="btn btn-secondary m-btn m-btn--air m-btn--custom"&gt;CANCEL&lt;/button&gt;
              &lt;button mat-button type="submit" ng-disabled="!flagForm.valid" color="primary" class="btn btn-accent m-btn m-btn--air m-btn--custom"&gt;Submit&lt;/button&gt;
            &lt;/div&gt;
          &lt;/form&gt;
        `
      })
      export class InlineEditComponent {
  
        flagFormControl = new FormControl('', [
          Validators.required
        ]);
  
        matcher = new MyErrorStateMatcher();
  
        /** Overrides the flag and provides a reset value when changes are cancelled. */
        @Input()
        get value(): string { return this._value; }
        set value(x: string) {
          this.flag = this._value = x;
        }
        private _value = '';
  
        /** Form model for the input. */
        flag = '';
  
        constructor(@Optional() @Host() public popover: SatPopover) { }
  
        ngOnInit() {
          // subscribe to cancellations and reset form value
          if (this.popover) {
            this.popover.closed.pipe(filter(val =&gt; val == null))
              .subscribe(() =&gt; this.flag = this.value || '');
          }
        }
  
        onSubmit() {
          if (this.popover) {
            this.popover.close(this.flag);
          }
        }
  
        onCancel() {
          if (this.popover) {
            this.popover.close();
          }
        }
      }
  </code></pre>