Search code examples
angulartypescriptangular-reactive-forms

Angular: Custom validation with parameter


I am trying to implement a verify password validation with Angular 6 using Reactive Form but I can't get the best way to do it, below an example that works with "1234" but I would like to pass the value of the password control instead. I tried with ValidatePWD(this) but doesn't work either.

 //component.ts
 import { ValidatePWD } from './compare.validator';

 this.form = this._fb.group({
                  'user': ['', Validators.compose([Validators.required])],                       
                  'password': ['', Validators.compose([Validators.required])],
                  'verifypassword': ['', [Validators.required, ValidatePWD]],

 });


//compare.validator.ts
import { AbstractControl, FormGroup } from '@angular/forms';
export function ValidatePWD(control: AbstractControl ) {    
  if (control.value != "1234") {
    return { validPWD: true };
  }
  return null;
}


<div class="form-group">
      <label>Password: {{model.password}}</label>
      <input [(ngModel)]="model.password" [formControl]="password" class="form-control" type="password">
</div>

<div class="form-group">
     <label >Verify Password</label>
     <input[(ngModel)]="model.verifypassword" [formControl]="verifypassword"  class="form-control" type="password">
</div>

enter image description here


Solution

  • Option 1 - Validate the password and verifyPassword through FormGroup,

    Here is simple sample code for confirm password validation where you need to pass the validator to FormGroup which contains both the contols password and confirmPassword.

      this.form = this._fb.group({
                  'user': ['', Validators.compose([Validators.required])],                       
                  'password': ['', Validators.compose([Validators.required])],
                  'verifypassword': ['', [Validators.required]],
    
      }, { validator: this.passwordMatchValidator });
    
      passwordMatchValidator(g: FormGroup) {
        return g.get('password').value === g.get('verifypassword').value
           ? null : {'mismatch': true};
      }
    

    html

    <div *ngIf="form.invalid && form.errors['mismatch']">Password did not match</div>
    

    Sample example is here -https://stackblitz.com/edit/confirm-password-q3ngps

    Option 2 - Use a function to match the password.

    password-validator.ts

    export class PasswordValidation {
    
        static MatchPassword(AC: AbstractControl) {
            let password = AC.get('password').value;
            if(AC.get('confirmPassword').touched || AC.get('confirmPassword').dirty) {
                let verifyPassword = AC.get('confirmPassword').value;
    
                if(password != verifyPassword) {
                    AC.get('confirmPassword').setErrors( {MatchPassword: true} )
                } else {
                    return null
                }
            }
        }
    }
    

    Component ts

    this.form = this._fb.group({
          password: ['', Validators.required],
          confirmPassword: ['', Validators.required]
        }, {
          validator: PasswordValidation.MatchPassword
        });
    

    Working copy is here - https://stackblitz.com/edit/material-password-confirm-pnnd4t