<mat-error> not working in a reactive form in an angular 8 application

1.9k views Asked by At

I am using a reactive approach to build a form, using angular and material. Somehow, one of the errors generated via custom validator is not showing up, while all other errors are working fine. Below is the code.

<div fxLayout="row" fxLayoutGap="10px" fxLayoutAlign="center center" formGroupName="passwords">
    <!--original password-->
    <mat-form-field hintLabel="Should be at least 8 characters long">
        <input type="password" matInput placeholder="Your password" formControlName="password">
        <mat-error *ngIf="signUpForm.get('passwords.password').hasError('required')">
            Passwords cannot be blank
        </mat-error>
        <mat-error *ngIf="signUpForm.get('passwords.password').hasError('minlength')">
            Password has to be atleast 8 characters
        </mat-error>
    </mat-form-field>
    <!--confirmation password-->
    <mat-form-field hintLabel="Should be at least 8 characters long">
        <input type="password" matInput placeholder="Confirm password" formControlName="confirmPassword">
            <mat-error *ngIf="signUpForm.get('passwords.confirmPassword').hasError('required')">
                Passwords cannot be blank
            </mat-error>
            <mat-error *ngIf="signUpForm.get('passwords.confirmPassword').hasError('minlength')">
                 Password has to be atleast 8 characters
            </mat-error>  
            <mat-error *ngIf="signUpForm.get('passwords').hasError('paswordMismatch')">
                Passwords do not match
           </mat-error>
    </mat-form-field>   
</div>

Here the <mat-error *ngIf="signUpForm.get('passwords').hasError('paswordMismatch')"> is not working.

below is the ts file

    ngOnInit(): void{
    
        this.signUpForm = this.formBuilder.group({
            studentName: this.formBuilder.group({
                firstName: [null, [Validators.required, Validators.pattern('[a-zA-Z]*')]],
                middleName: [null, [Validators.pattern('[a-zA-Z]*')]],
                lastName: [null, [Validators.pattern('[a-zA-Z]*')]] }),
            email: [null, [Validators.required, Validators.email,
                  CustomEmailValidator.forbiddenEmailIds]],
            userMobNumber: [null, [Validators.required, Validators.minLength(10), 
                  Validators.maxLength(10)]],
            studentID: [null, [Validators.required]],
            passwords: this.formBuilder.group({
                password: [null, [Validators.required, Validators.minLength(8)]],
                confirmPassword: [null, [Validators.required, Validators.minLength(8)]]
            }, {validator: this.passwordConfirming}),
            enroledProgram: [null, [Validators.required]],
            studentDepartment: [null, [Validators.required]],
            facultyDepartment: [null, [Validators.required]],
            facultyEmail: [null, [Validators.required, Validators.email]],
            facultyName: [null, [Validators.required]],
            funded: [null, [Validators.required]]
            });}
        
          passwordConfirming(c: AbstractControl): { [s: string]: boolean } { 
               console.log(c);
              if (c.get('password').value !== c.get('confirmPassword').value) {
                 return {paswordMismatch: true};
              }
          return null;
        }
    ```

2

There are 2 answers

1
sun sreng On

It should be

<div fxLayout="row" fxLayoutGap="10px" fxLayoutAlign="center center" formGroupName="passwords">
... 
            <mat-error *ngIf="signUpForm.get('passwords.confirmPassword').hasError('paswordMismatch')">
                Passwords do not match
           </mat-error>
    </mat-form-field>   
</div>
0
Tina On

Create another file named "password.validator.ts" and write the following code:

import { AbstractControl, ValidatorFn } from "@angular/forms";

export function passwordValidator(
  control: AbstractControl
): {
  [key: string]: boolean;
} | null {


  const password = control.get("password");
  const confirmPassword = control.get("confirmPassword");
  if (password.pristine || confirmPassword.pristine) {
    return null;
  }
  return password && confirmPassword && password.value !== confirmPassword.value
    ? { missMatch: true }
    : null;
}

**on the File where the form exists: add the password validator like this-- **

import { passwordValidator } from "./password.validator";

this.signUpForm = this.formBuilder.group({
            passwords: this.formBuilder.group({
                password: [null, [Validators.required, Validators.minLength(8)]],
                confirmPassword: [null, [Validators.required, Validators.minLength(8)]]
            }, { validators: [passwordValidator]})}