Confirm password validation in Angular 6 [duplicate] Confirm password validation in Angular 6 [duplicate] angular angular

Confirm password validation in Angular 6 [duplicate]


This question could be solved with a combination of these two answers: https://stackoverflow.com/a/43493648/6294072 and https://stackoverflow.com/a/47670892/6294072

So first of all, you would need a custom validator for checking the passwords, that could look like this:

checkPasswords: ValidatorFn = (group: AbstractControl):  ValidationErrors | null => {   let pass = group.get('password').value;  let confirmPass = group.get('confirmPassword').value  return pass === confirmPass ? null : { notSame: true }}

and you would create a formgroup for your fields, instead of just two form controls, then mark that custom validator for your form group:

this.myForm = this.fb.group({  password: ['', [Validators.required]],  confirmPassword: ['']}, { validators: this.checkPasswords })

and then as mentioned in other answer, the mat-error only shows if a FormControl is invalid, so you need an error state matcher:

export class MyErrorStateMatcher implements ErrorStateMatcher {  isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean {    const invalidCtrl = !!(control?.invalid && control?.parent?.dirty);    const invalidParent = !!(control?.parent?.invalid && control?.parent?.dirty);    return invalidCtrl || invalidParent;  }}

in the above you can tweak when to show error message. I would only show message when the password field is touched. Also I would like above, remove the required validator from the confirmPassword field, since the form is not valid anyway if passwords do not match.

Then in component, create a new ErrorStateMatcher:

matcher = new MyErrorStateMatcher();

Finally, the template would look like this:

<form [formGroup]="myForm">  <mat-form-field>    <input matInput placeholder="New password" formControlName="password" required>    <mat-error *ngIf="myForm.hasError('required', 'password')">      Please enter your new password    </mat-error>  </mat-form-field>  <mat-form-field>    <input matInput placeholder="Confirm password" formControlName="confirmPassword" [errorStateMatcher]="matcher">    <mat-error *ngIf="myForm.hasError('notSame')">      Passwords do not match    </mat-error>    </mat-form-field></form>

Here's a demo for you with the above code: StackBlitz


You can simply use password field value as a pattern for confirm password field.For Example :

<div class="form-group"> <input type="password" [(ngModel)]="userdata.password" name="password" placeholder="Password" class="form-control" required #password="ngModel" pattern="(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,}" /> <div *ngIf="password.invalid && (myform.submitted || password.touched)" class="alert alert-danger">   <div *ngIf="password.errors.required"> Password is required. </div>   <div *ngIf="password.errors.pattern"> Must contain at least one number and one uppercase and lowercase letter, and at least 8 or more characters.</div> </div></div><div class="form-group"> <input type="password" [(ngModel)]="userdata.confirmpassword" name="confirmpassword" placeholder="Confirm Password" class="form-control" required #confirmpassword="ngModel" pattern="{{ password.value }}" /> <div *ngIf=" confirmpassword.invalid && (myform.submitted || confirmpassword.touched)" class="alert alert-danger">   <div *ngIf="confirmpassword.errors.required"> Confirm password is required. </div>   <div *ngIf="confirmpassword.errors.pattern"> Password & Confirm Password does not match.</div> </div></div>


The simplest way imo:

(It can also be used with emails for example)

public static matchValues(    matchTo: string // name of the control to match to  ): (AbstractControl) => ValidationErrors | null {    return (control: AbstractControl): ValidationErrors | null => {      return !!control.parent &&        !!control.parent.value &&        control.value === control.parent.controls[matchTo].value        ? null        : { isMatching: false };    };}

In your Component:

this.SignUpForm = this.formBuilder.group({password: [undefined, [Validators.required]],passwordConfirm: [undefined,         [          Validators.required,          matchValues('password'),        ],      ],});

Follow up:

As others pointed out in the comments, if you fix the error by fixing the password field the error won't go away, Because the validation triggers on passwordConfirm input. This can be fixed by a number of ways. I think the best is:

this.SignUpForm .controls.password.valueChanges.subscribe(() => {  this.SignUpForm .controls.confirmPassword.updateValueAndValidity();});

On password change, revliadte confirmPassword.