title: Angular reactive form is invalid on page load
body: <p>I have a form where three of my inputs (two fields and 1 checkbox) are <code>ng-invalid</code> when the page first loads. The checkbox is the one I'm most concerned about, <a href="https://i.stack.imgur.com/Hif0m.png" rel="nofollow noreferrer">because it appears with a red border</a> (&quot;this field is required&quot;) right off the bat. <code>ng-invalid</code> as a class is setting that red border, while <code>ng-valid</code> sets a grey border (which I want).</p>
  <p>There's some other fields on the page but they're disabled and neither invalid nor valid.</p>
  <p>What is setting the form fields as <code>ng-invalid</code>? I'm suspecting that there's something wrong with how my <code>FormGroup</code> and controls are set up, but I'm not sure what the culprit is. I noticed that <code>ng-invalid</code> <em>is</em> being added to the <code>FormGroup</code> itself, so to me solving that's the key to resolving this.</p>
  <hr />
  <h3>component.ts</h3>
  <pre class="lang-js prettyprint-override"><code>  constructor(
      private cdr: ChangeDetectorRef,
      private formBuilder: FormBuilder
    ) { }
  
    myFormGroup = this.formBuilder.group({
        // other FormControls
        password: new FormControl('', [Validators.required, Validators.minLength(MIN_PW)]),
        confirmPassword: new FormControl('', Validators.required),
        myCheckbox: new FormControl('', Validators.required)
      }, { validator: PasswordValidation.MatchPassword }
    );
  
    ngOnInit(): void {
      // etc
    }
  </code></pre>
  <h3>template:</h3>
  <pre class="lang-html prettyprint-override"><code>
  &lt;form [formGroup]=&quot;myFormGroup&quot; #myNgForm=&quot;ngForm&quot; class=&quot;my-form&quot;&gt;
  
    &lt;div&gt;
        &lt;mat-form-field appearance=&quot;outline&quot; class=&quot;password-field half-width&quot;&gt;
          &lt;input matInput [type]=&quot;hidePassword ? 'password' : 'text'&quot; formControlName=&quot;password&quot;&gt;
          &lt;mat-error *ngIf=&quot;myFormGroup.controls['password'].invalid&quot;&gt;Password is required and must contain at least 8 characters.&lt;/mat-error&gt;
          &lt;button mat-icon-button matSuffix (click)=&quot;hidePassword = !hidePassword&quot; [attr.aria-label]=&quot;'Hide password'&quot; [attr.aria-pressed]=&quot;hidePassword&quot;&gt;
            &lt;mat-icon&gt;{{hidePassword ? 'visibility_off' : 'visibility'}}&lt;/mat-icon&gt;
          &lt;/button&gt;
          &lt;mat-label&gt;Password&lt;/mat-label&gt;
          &lt;mat-hint&gt;Must be at least 8 characters&lt;/mat-hint&gt;
        &lt;/mat-form-field&gt;
  
        &lt;mat-form-field appearance=&quot;outline&quot; class=&quot;ml-16 password-field half-width&quot;&gt;
          &lt;input matInput [type]=&quot;hidePassword ? 'password' : 'text'&quot; formControlName=&quot;confirmPassword&quot;&gt;
          &lt;mat-error *ngIf=&quot;myFormGroup.controls['confirmPassword'].pristine || myFormGroup.controls['confirmPassword'].errors?.MatchPassword&quot;&gt;Passwords do not match&lt;/mat-error&gt;
          &lt;button mat-icon-button matSuffix (click)=&quot;hidePassword = !hidePassword&quot; [attr.aria-label]=&quot;'Hide password'&quot; [attr.aria-pressed]=&quot;hidePassword&quot;&gt;
            &lt;mat-icon&gt;{{hidePassword ? 'visibility_off' : 'visibility'}}&lt;/mat-icon&gt;
          &lt;/button&gt;
          &lt;mat-label&gt;Confirm password&lt;/mat-label&gt;
        &lt;/mat-form-field&gt;
  
      &lt;/div&gt;
  
      &lt;div&gt;
        &lt;p class=&quot;full-width&quot;&gt;
          &lt;mat-checkbox formControlName=&quot;myCheckbox&quot; required&gt;some text&lt;/mat-checkbox&gt;
        &lt;/p&gt;
      &lt;/div&gt;
  
  &lt;/form&gt;
  
  </code></pre>
  <hr />
  <p>Here's the <code>ng-invalid</code> class on the checkbox.</p>
  <p><a href="https://i.stack.imgur.com/EHBmL.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/EHBmL.png" alt="enter image description here" /></a></p>