angularvalidationangular5angular2-formscustomvalidator

Custom password match validator is not working in angular5


I am implementing custom validator to match password in my component.

Here is my component.ts form declaration

this.addUserForm = new FormGroup({
  firstname: new FormControl('', [Validators.required]),
  lastname: new FormControl('', [Validators.required]),
  city: new FormControl(),
  address: new FormControl(),
  email: new FormControl('', [Validators.required, Validators.email]),
  password: new FormControl('', [Validators.required, Validators.minLength(6)]),
  confirm_password: new FormControl('', [Validators.required, ConfirmPasswordValidator.MatchPassword]),
  role: new FormControl('', [Validators.required]),
  phone: new FormControl(),
  companyCode: new FormControl(this.local_storage.getCurrentUser().companyCode, [Validators.required])
});

here is my custom.validator.ts

import { AbstractControl } from '@angular/forms';

export class ConfirmPasswordValidator {
static MatchPassword(control: AbstractControl) {
    let password = control.get('password').value;
    let confirmPassword = control.get('confirm_password').value;

    if (password != confirmPassword) {
        console.log('false')
        control.get('confirmPassword').setErrors({ ConfirmPassword: true });
    } else {
        return null
    }
  }
 }

Here is my component.html input part

 <label class="col-form-label">Password</label>
        <div class="form-group row">
          <div class="col-sm-10">
            <input type="password" class="form-control" formControlName="password">
            <div class="alert alert-danger" *ngIf="addUserForm.get('password').touched && addUserForm.get('password').invalid && addUserForm.get('password').errors.required">
              Password is required
            </div>
            <div class="alert alert-danger" *ngIf="addUserForm.get('password').touched && addUserForm.get('password').invalid && addUserForm.get('password').errors.minlength && !addUserForm.get('password').errors.required">
              Password length must be greater than 6
            </div>
          </div>
        </div>
       <div class="alert alert-danger" *ngIf="addUserForm.get('confirm_password').touched && addUserForm.get('confirm_password').invalid && addUserForm.get('confirm_password').errors.ConfirmPassword">
              Password deesn't match
          </div>

But it is giving this error property 'value' of null TypeError: Cannot read property 'value' of null at ConfirmPasswordValidator.MatchPassword (user.validator.ts:5) Project structure and directory is very complex and huge that's why can't share all component and html code. What's wrong in my code?


Solution

  • Form Group Validator

    Update MatchPassword to work on form group level so you don't need to add a custome validator to confirmPassword control

    static MatchPassword(control: AbstractControl) {
        let password = control.get('password').value;
        let confirmPassword = control.get('confirm_password').value;
    
        if (password != confirmPassword) {
          return { ConfirmPassword: true };
        } else {
            return null
        }
      }
    

    and add this validator for formGroup validators options

    { validators: ConfirmPasswordValidator.MatchPassword }
    

    stackblitz demo 🚀🚀

    Form Control Validator

    if you want to add the validation to the control so the control parameter will be confirm password control and you need to use parent to access to the form group and get the value of password control

    this.form = fb.group({
      password: [null, [Validators.required]],
      confirm_password: [null, [Validators.required, MatchPassword]]
    })
    

    MatchPassword validator

    function MatchPassword(control: AbstractControl) {
      let parent = control.parent
      if (parent) {
        let password = parent.get('password').value;
        let confirmPassword = control.value;
    
        if (password != confirmPassword) {
          return { ConfirmPassword: true };
        } else {
          return null
        }
      } else {
        return null;
      }
    

    stackblitz demo 🚀🚀