title: Ionic 3 form validation confirm password
body: <p>I am building registration form in Ionic 3, I have two fields password1 and password2 and the requirement is password2 must be same as password1.</p>
  
  <p>My component:</p>
  
  <pre><code>public registration : FormGroup;
  
      constructor(private formBuilder: FormBuilder) {
  
          this.registration = this.formBuilder.group({
              username: ['', Validators.compose([Validators.pattern('^(?=.*[a-zA-Z])(?=.*[0-9])[a-zA-Z0-9]+$'), Validators.required])],
              email: ['', Validators.compose([Validators.email, Validators.required])],
              password1: ['', Validators.compose([Validators.minLength(5), Validators.pattern('^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])[a-zA-Z0-9]+$'), Validators.required])],
              password2: ['', Validators.required],
          }, (registration: FormGroup) =&gt; {
              return PasswordValidator.areEqual(registration);
          });
      }
  
      validation_messages = {
          'username': [
          { type: 'pattern', message: 'Username must contain only combination of letterns and numbers.' },
          { type: 'required', message: 'Username is required.' }
          ],
          'email': [
          { type: 'required', message: 'Email is required.' },
          { type: 'email', message: 'Not a valid email!' }
          ],
          'password1': [
          { type: 'minlength', message: 'Password must be minimum 5 characters.' },
          { type: 'required', message: 'Password is required.' },
          { type: 'pattern', message: 'Password must contain combination of upper and lower case letterns and numbers.' }
          ],
          'password2': [
          { type: 'required', message: 'Password is required.' },
          { type: 'areEqual', message: 'Confirm password is not same.' },
          ],
  
      }
  </code></pre>
  
  <p>I have created a password validator in a separate file (not sure if it's the correct way):</p>
  
  <pre><code>import { FormControl, FormGroup } from '@angular/forms';
  
  export class PasswordValidator {
  static areEqual(formGroup: FormGroup) {
      let val;
      let valid = true;
  
      for (let key in formGroup.controls) {
          if (formGroup.controls.hasOwnProperty(key)) {
              let control: FormControl = &lt;FormControl&gt;formGroup.controls[key];
              if (val === undefined) {
                  val = control.value
              } else {
                  if (val !== control.value) {
                      valid = false;
                      break;
                  }
              }
          }
      }
      if (valid) {
          return null;
      }
      return {
          areEqual: true
      }
   }
  }
  </code></pre>
  
  <p>And my template:</p>
  
  <pre><code>&lt;!-- Registration Form --&gt;
  &lt;form *ngSwitchCase="'registrationForm'" [formGroup]="registration" (ngSubmit)="register()" autocomplete="off"&gt;
  
      &lt;ion-item&gt;
          &lt;ion-label&gt;Username&lt;/ion-label&gt;
          &lt;ion-input type="text" formControlName="username"&gt;&lt;/ion-input&gt;
      &lt;/ion-item&gt;
      &lt;!-- Username validation errors --&gt;
      &lt;div class="validation-errors"&gt;
          &lt;ng-container *ngFor="let validation of validation_messages.username" &gt;
              &lt;div class="error-message" *ngIf=" registration.get('username').hasError(validation.type) 
              &amp;&amp; ( registration.get('username').dirty || registration.get('username').touched)"&gt;
                  {{ validation.message }}
              &lt;/div&gt;
          &lt;/ng-container&gt;
      &lt;/div&gt;
  
  
      &lt;ion-item&gt;
          &lt;ion-label&gt;Email&lt;/ion-label&gt;
          &lt;ion-input type="email" formControlName="email"&gt;&lt;/ion-input&gt;
      &lt;/ion-item&gt;
      &lt;!-- Email validation errors --&gt;
      &lt;div class="validation-errors"&gt;
          &lt;ng-container *ngFor="let validation of validation_messages.email" &gt;
              &lt;div class="error-message" *ngIf=" registration.get('email').hasError(validation.type) 
              &amp;&amp; ( registration.get('email').dirty || registration.get('email').touched)"&gt;
                  {{ validation.message }}
              &lt;/div&gt;
          &lt;/ng-container&gt;
      &lt;/div&gt;
  
  
      &lt;ion-item&gt;
          &lt;ion-label&gt;Password1&lt;/ion-label&gt;
          &lt;ion-input type="password" formControlName="password1"&gt;&lt;/ion-input&gt;
      &lt;/ion-item&gt;
      &lt;!-- Password1 validation errors --&gt;
      &lt;div class="validation-errors"&gt;
          &lt;ng-container *ngFor="let validation of validation_messages.password1" &gt;
              &lt;div class="error-message" *ngIf=" registration.get('password1').hasError(validation.type) 
              &amp;&amp; ( registration.get('password1').dirty || registration.get('password1').touched)"&gt;
                  {{ validation.message }}
              &lt;/div&gt;
          &lt;/ng-container&gt;
      &lt;/div&gt;
  
      &lt;ion-item&gt;
          &lt;ion-label&gt;Password2&lt;/ion-label&gt;
          &lt;ion-input type="password" formControlName="password2"&gt;&lt;/ion-input&gt;
      &lt;/ion-item&gt;
      &lt;!-- Password2 validation errors --&gt;
      &lt;div class="validation-errors"&gt;
          &lt;ng-container *ngFor="let validation of validation_messages.password2" &gt;
              &lt;div class="error-message" *ngIf=" registration.get('password2').hasError(validation.type) 
              &amp;&amp; ( registration.get('password2').dirty || registration.get('password2').touched)"&gt;
                  {{ validation.message }}
              &lt;/div&gt;
          &lt;/ng-container&gt;
      &lt;/div&gt;
  
      &lt;button ion-button full type="submit" [disabled]="!registration.valid"&gt;Submit&lt;/button&gt;
  &lt;/form&gt;
  </code></pre>
  
  <p>All other validations work properly i.e. correct messages are printed. Password2 validation works only for empty password and do not work for checking if it is same with password1.</p>
  
  <p>What am I doing wrong?</p>