1

I am trying to implement password and confirm password validation in an angular project. I followed the answer on this post Confirm password validation in Angular 6. However I am unable to get any error message. I don't know what I'm doing wrong. here is my ts code:

  constructor(private formBuilder:FormBuilder,private userService:UsersService,private router:Router) { }
  addForm: FormGroup;
  selected = 'option2';
  passwordsMatcher = new RepeatPasswordEStateMatcher;

  ngOnInit() {

    this.addForm = this.formBuilder.group({
      id: [],
      userName: ['', Validators.required],
      password:new FormControl( '',[ Validators.required]),
      passwordAgain: new FormControl('',[ Validators.required]),
      userRole:['',Validators.required],

    },{ validator: RepeatPasswordValidator });
  }
  onSubmit() {
    if (this.addForm.valid)
    {
    this.userService.createUser(this.addForm.value)
      .subscribe( data => {
        this.router.navigate(['newuser']);
      });
    console.log(this.addForm.controls.password.value);
  }
}
  changeClient(value) {
    console.log(value);
    console.log(this.addForm.controls.value);
}

here is my validator code:

export class RepeatPasswordEStateMatcher implements ErrorStateMatcher {
  isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean {
    return (control && control.parent.get('password').value !== control.parent.get('passwordAgain').value)
  }
}
export function RepeatPasswordValidator(group: FormGroup) {
  let password = group.controls.password.value;
  let passwordConfirmation = group.controls.passwordAgain.value;

  return password === passwordConfirmation ? null: { passwordsNotEqual: true }     
}

Below is my template:

<div  style="height: 100vh" fxLayout="column" fxLayoutAlign="center center" >
    <h2 class="text-center">Add User</h2>
    <mat-card>
        <mat-card-content>

    <form [formGroup]="addForm" class="login-form" (ngSubmit)="onSubmit()">
    <div class="form-group">
        <mat-form-field class="example-full-width">

      <input matInput type="text" formControlName="userName" placeholder="userName" name="userName" class="form-control" id="userName">
        </mat-form-field>
    </div>

    <div class="form-group">
        <mat-form-field class="example-full-width">

      <input matInput type="password" formControlName="password" placeholder="Password" name="password" class="form-control" id="password">
      <mat-error *ngIf="addForm.controls.password.hasError('required')" >Passwords can't be empty</mat-error>
    </mat-form-field>
    </div>
    <div class="form-field">
        <mat-form-field>
        <input matInput formControlName="passwordAgain" placeholder="Confirm the password" type="password" [errorStateMatcher]="passwordsMatcher">
        <mat-error *ngIf="addForm.controls.passwordAgain.hasError('passwordsNotEqual')" >Passwords are different. They should be equal!</mat-error>
        </mat-form-field>
    </div>
    <mat-form-field>
        <mat-select placeholder="Roles" formControlName="userRole" id="userRole" (selectionChange)="changeClient($event.value)" [(value)]="selected">
          <mat-option value="Admin">Admin</mat-option>


        </mat-select>
      </mat-form-field>

      <div class="container" style="margin: 12px" fxLayout="row" fxLayoutAlign="center center">


    <button mat-raised-button color="primary">Create</button>
      </div>
  </form>
  </mat-card-content>
    </mat-card>
</div>

Please help.Thanks in advance.

rock11
  • 718
  • 4
  • 17
  • 34

1 Answers1

0

You are checking the equality of the two fields password and passwordAgainin the matcher which is already done in validator,

The work of the matcher is to check if the error Message should be shown or not, in your case the error message should appear when addForm has an passwordsNotEqual.

Since the validator is applied on the FormGroup not on the FormControl so in the matcher you have to check the validity of the FormGroup.

So what i suggest is to modify isErrorState method like this :

isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean {
    return !!(control && control.parent && control.parent.invalid && control.parent.dirty);
}

And In HTML you should check the formGroup errors not formControl.( because again the validator is applied on addForm not on passwordAgain)

    <mat-error *ngIf="addForm.hasError('passwordsNotEqual')" >Passwords are different. They should be equal!</mat-error>
    <!-- instead of addForm.controls.passwordAgain.hasError('passwordsNotEqual') --> 

This will for sure work for you.

Mohamed Ali RACHID
  • 3,245
  • 11
  • 22