Angular 11 How to validate confirmPassword is same as password using Reactive forms
Asked Answered
K

3

6
import { Component, OnInit } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';

@Component({
  selector: 'app-user-register',
  templateUrl: './user-register.component.html',
  styleUrls: ['./user-register.component.css']
})
export class UserRegisterComponent implements OnInit {

  registerationForm: FormGroup = new FormGroup({});
  constructor() { }

  ngOnInit() {
    this.registerationForm = new FormGroup({
      userName : new FormControl(null, Validators.required),
      email : new FormControl(null, [Validators.required, Validators.email]),
      password : new FormControl(null, [Validators.required, Validators.minLength(8)]),
      confirmPassword : new FormControl(null, [Validators.required]),
      mobile : new FormControl(null, [Validators.required, Validators.minLength(10)])
    }, this.passwordMatchingValidatior);
  }
  passwordMatchingValidatior(fg: FormGroup): Validators{
    return this.registerationForm.get('password').value === this.registerationForm.get('confirmPassword').value ? null : {notmatched: true};
  }
  onSubmit(){
    console.log(this.registerationForm);
  }
}

error message Error: src/app/user/user-register/user-register.component.ts:24:5 - error TS2322: Type '{ notmatched: boolean; } | null' is not assignable to type 'Validators'. Type 'null' is not assignable to type 'Validators'.

24 return this.registerationForm.get('password').value === this.registerationForm.get('confirmPassword').value ? null : {notmatched: true};

Error: src/app/user/user-register/user-register.component.ts:24:61 - error TS2531: Object is possibly 'null'.

24 return this.registerationForm.get('password').value === this.registerationForm.get('confirmPassword').value ? null : {notmatched: true};

Kitchens answered 23/4, 2021 at 14:33 Comment(0)
A
12

According to angular docs - Adding cross-validation to reactive forms

create your validator

export const passwordMatchingValidatior: ValidatorFn = (control: AbstractControl): ValidationErrors | null => {
  const password = control.get('password');
  const confirmPassword = control.get('confirmPassword');

  return password?.value === confirmPassword?.value ? null : { notmatched: true };
};

and update formgroup validator

this.registerationForm = new FormGroup({
      userName: new FormControl(null, Validators.required),
      email: new FormControl(null, [Validators.required, Validators.email]),
      password: new FormControl(null, [Validators.required, Validators.minLength(8)]),
      confirmPassword: new FormControl(null, [Validators.required]),
      mobile: new FormControl(null, [Validators.required, Validators.minLength(10)])
    }, { validators: passwordMatchingValidatior });
Astylar answered 23/4, 2021 at 15:9 Comment(0)
W
1

Try these changes.

@Component({
  selector: 'app-user-register',
  templateUrl: './user-register.component.html',
  styleUrls: ['./user-register.component.css']
})
export class UserRegisterComponent implements OnInit {

  registerationForm: FormGroup = new FormGroup({});
  constructor() { }

  ngOnInit() {
    this.registerationForm = new FormGroup({
      userName : new FormControl(null, Validators.required),
      email : new FormControl(null, [Validators.required, Validators.email]),
      password : new FormControl(null, [Validators.required, Validators.minLength(8)]),
      confirmPassword : new FormControl(null, [Validators.required]),
      mobile : new FormControl(null, [Validators.required, Validators.minLength(10)])
    }, this.passwordMatchingValidatior);
  }

  passwordMatchingValidatior(form: FormGroup): null => {
     const password = form.controls['password'].value;
     const confirmation = form.controls['confirmPassword'].value;

     if (!password || !confirmation) { // if the password or confirmation has not been inserted ignore
       return null;
     }
     
     if (confirmation.length > 0 && confirmation !== password) {
       confirmation.setErrors({ notMatch: true }); // set the error in the confirmation input/control
     }

     return null; // always return null here since as you'd want the error displayed on the confirmation input
  }

  onSubmit(){
    console.log(this.registerationForm);
  }
}
Whoredom answered 23/4, 2021 at 14:44 Comment(0)
W
1

Create the new validator validateAreEqual and reference in the form group itself, instead of in the form control:

import { AbstractControl, FormControl, FormGroup, Validators } from '@angular/forms';

public newForm: FormGroup | any;

ngOnInit(): void {
  this.newForm = new FormGroup({
    password: new FormControl(null, [Validators.required]),
    confirm: new FormControl(null, [Validators.required])
  }, {validators: this.validateAreEqual})
}

public validateAreEqual(c: AbstractControl): { notSame: boolean } | null {
  return c.value.password === c.value.confirm ? null : { notSame: true };
}

Then if you want, you can show the error later:

<span class="error-text" *ngIf="newForm.get('confirm').touched &&  newForm.errors['notSame']">Password mismatch</span>
Wast answered 4/11, 2022 at 16:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.