Angular validation for password and confirmation password fields

I have been working on implementing password and confirm password validation within an angular project. I recently came across a helpful answer on this thread Confirm password validation in Angular 6 that I tried to follow. Unfortunately, I am encountering issues with not receiving any error messages, and I am unsure of what mistake I might be making. Below is the TypeScript code I am using:

  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);
}

My current validator implementation looks like this:

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 }     
}

Furthermore, here is the template structure I've set up:

<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 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>

If anyone could provide some assistance or guidance on my current setup, I would greatly appreciate it. Thank you.

Answer №1

Ensuring the equality of the fields password and passwordAgain is being checked in the matcher, although it is already done in the validator.

The purpose of the matcher is to determine if the error message should be displayed or not. In this scenario, the error message will only show when addForm contains an error called passwordsNotEqual.

Considering that the validator is applied on the FormGroup rather than on the FormControl, it is necessary to verify the validity of the FormGroup within the matcher.

Therefore, I recommend modifying the isErrorState method as follows:

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

In the HTML code, make sure to check for errors in the formGroup rather than the formControl. This adjustment is crucial because the validator is implemented on addForm and 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') --> 

These modifications will certainly resolve the issue at hand.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Encountering an issue with TypeScript error code TS2322 when trying to assign a className to the @

Encountering a typescript error when trying to apply a className to a Box element. Interestingly, the same code works on other developers' machines with almost identical configurations. Current dependencies: "@material-ui/core": "4.11. ...

"When a class extends another class and utilizes properties within a static property, it essentially becomes

I have been encountering challenges with generics in TypeScript for quite some time now. My current setup is as follows: First, there is a generic class defined as: class Entity { public static schema = {}; } Then, there is a class that extends the ...

How can I populate separate lists with data from an Angular GET request response?

I am new to using Angular and I have been struggling to build a frontend application that can consume my REST API created with Django. Despite searching for two days, I have not found a satisfactory answer to my problem. Chat GPT also seems to be inaccessi ...

Differentiating body classes in Angular 5

I am working on a project with both a login screen and a dashboard screen. The body classes for these screens are different, as shown below: <body class="hold-transition skin-black-light sidebar-mini" > // for dashboard <body class="hold-transi ...

Angular - developing a custom web element to enhance the project

Is there a way to convert a single module into a web component and integrate it within the same project? Specifically, I have 3 modules in my project and I am looking to transform only module1 into a web component and incorporate it seamlessly. Thank you! ...

Ionic 2 fails to navigate when using [navPush]

Today I delved into working with Ionic 2 and was making good progress. I had successfully implemented navigation across 3-4 pages, but then something suddenly broke that has left me scratching my head. Now whenever I try to navigate to another page, I kee ...

Angular 7 form does not automatically disable the button upon initialization

My current challenge involves disabling a button until a form is completely filled out. Surprisingly, everything works perfectly in Chrome and Firefox, but IE11 seems to be causing some issues. Below is the relevant code snippet: <div class="col-12"> ...

What is the process for incorporating personalized variables into the Material Ui Theme?

In the process of developing a react app with TypeScript and Material UI, I encountered an issue while attempting to define custom types for my themes. The error message I received is as follows: TS2322: Type '{ mode: "dark"; background: { default: s ...

Error: Unable to Locate Module (Typescript with baseUrl Configuration)

Struggling to implement custom paths in my TypeScript project, I keep encountering the "webpackMissingModule" error due to webpack not recognizing my modules. I've attempted various solutions without any success. Any suggestions or ideas? Some packa ...

Is there a way to link my ionic application to dual API URLs within a single webpage? Additionally, how can I transfer the ID from the information received from the first URL to the second URL efficiently?

I am currently in the process of developing an Ionic recipe application. The home page is designed to display a list of recipes names, ids, and images by fetching data from an API endpoint at www.forexample/recipeslist.com. My goal is to create functiona ...

Encountering npm3 installation errors with typyings in Angular 2?

Each time I try to sudo npm install Angular 2 modules, everything updates and installs correctly. However, I encounter the following error when the typings install is attempted: <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="0 ...

The state is accurate despite receiving null as the return value

I'm feeling a bit lost here. I have a main component that is subscribing to and fetching data (I'm using the redux dev tools to monitor it and it's updating the state as needed). In component A, I am doing: public FDC$ = this.store.pipe(sel ...

Data bindings encapsulated within nested curly braces

I am currently utilizing Angular2 in my application. Within my html file, I have a *ngFor loop set up like so: <div *ngFor="let element of array"> {{element.id}} </div> Next, I have an array containing objects structured as follows: some ...

Trigger event with stream as data

I have a front-end application built with Angular that uses ngrx/store to manage the state of the application. In the main component of my application, I am trying to trigger an action to control the visibility of a sidebar in the application state. Curre ...

Error: Unable to access the 'visitStatement' property of an undefined object within Angular 2

Help! I encountered an error in my angular2 application. The error message says: TypeError: Cannot read property ‘visitStatement’ of undefined ...

Exploring the differences between initializing class members and using setters and getters in Typescript

Here is the code snippet that I am working with: export class Myclass { private _someVal = 2; public get someVal() { return this._someVal; } public set someVal(val) { this._someVal = val; } } In my template, I have <span&g ...

Mismatch between generic types

When working with this code, I encounter a syntax error at m1 and m2. The error message states: Type 'T' is not assignable to Type 'boolean' or Type 'T' is not assignable to Type 'string' interface customMethod { ...

Unable to confirm the version of Angular

I am currently using node version 10.14.1 and npm version 6.4.1 with angular version 7.0.3 installed. However, when I try to check the angular version by running the ng --version command, I encounter an error message in the command prompt. C:\Users&b ...

What is the best way to transform an array of objects into a nested array through shuffling

I am dealing with a diverse array of objects, each structured in a specific way: data = [ { content: { ..., depth: 1 }, subContent: [] }, { content: { ..., depth: 2 ...

Async pipe in Angular does not work with my custom observables

I've been trying to implement the async pipe in my template, but I'm encountering difficulties retrieving data from my API. To store and retrieve the data, I have utilized a behavior subject to create an observable. However, when I attempt to dis ...