5

i have attached my code below .im facing problem in adding password mismatch validation.im not getting validation error if i type mismatching password

register.component.html

<div class="form-group row mt-3">
 <label class="col-md-4 col-lg-4 text-center">UserName:<span style="color:red">*</span></label>
<input kendoTextBox required type="text" class="  col-md-6 col-lg-6 form-control " placeholder="Enter Your UserName " formControlName="username"/>
  <div *ngIf="(submitted||f2.username.touched) && f2.username.invalid" class="error-msg">
 <div *ngIf="f2.username.errors.required">UserName  is required</div>
 </div> </div>
 <div class="form-group row">
<label class="col-md-4 col-lg-4 text-center">Password:<span style="color:red">*</span></label>
<input kendoTextBox type="password" required  class="  col-md-6 col-lg-6 form-control " placeholder="Enter Your passowrd " formControlName="password"/>

 <div *ngIf="(submitted||f2.password.touched) && f2.password.invalid" class="error-msg">
<div *ngIf="f2.password.errors.required">password  is required</div>
<div *ngIf="f2.password.errors.minlength">minimum of 6 characters required</div>
    </div>
</div>
<div class="form-group row">
   <label class="col-md-4 col-lg-4 text-center">ConfirmPassword:
<span style="color:red">*</span></label>
<input kendoTextBox required type="password" class="  col-md-6 col-lg-6 form-control " placeholder="Enter Your new password " formControlName="confirmpassword"/>
 <div *ngIf="(submitted||f2.confirmpassword.touched) && f2.confirmpassword.invalid" class="error-msg">
 <div *ngIf="f2.confirmpassword.errors.required"> confirm password  is required</div>  <div *ngIf="f2.confirmpassword.errors.minlength">minimum of 6 characters required
</div>
<div class="error-msg" *ngIf="f2.errors?.mismatch && (f2.controls['confirmpassword'].required || f2.controls['confirmpassword'].touched)">
                              Passwords don't match.
</div>
                          </div>
                      </div>
    enter code here

registercomponent.ts file

here i have used formBuilder.other things are working fine ,only validation for mismatching not working

 this.registerForm3 = this.formBuilder.group({
    username:['', Validators.required],
    password: ['', [Validators.required, Validators.minLength(6)]],
    confirmpassword:['', [Validators.required, Validators.minLength(6)]],
  },
  {validator: this.passwordMatchValidator},
  );

passwordMatchValidator(frm: FormGroup) {
eturn frm.controls['password'].value === 
frm.controls['confirmpassword'].value ? null : {'mismatch': true};
    }
 get f2() { 
    return this.registerForm3.controls; 
  }
1

5 Answers 5

9

I didn't think that you could use a component member function (method) for your custom validator. I assumed it needed to be a function external from your class.

Mine looks like this:

function emailMatcher(c: AbstractControl): { [key: string]: boolean } | null {
  const emailControl = c.get('email');
  const confirmControl = c.get('confirmEmail');

  if (emailControl.pristine || confirmControl.pristine) {
    return null;
  }

  if (emailControl.value === confirmControl.value) {
    return null;
  }
  return { 'match': true };
}

And I attach the validator to a child formGroup like so:

this.customerForm = this.fb.group({
  firstName: ['', [Validators.required, Validators.minLength(3)]],
  lastName: ['', [Validators.required, Validators.maxLength(50)]],
  emailGroup: this.fb.group({
    email: ['', [Validators.required, Validators.email]],
    confirmEmail: ['', Validators.required],
  }, { validator: emailMatcher }),
  phone: ''
});

You could put your validator in a separate file, or in the same file either above or below your component class. Something like this:

function passwordMatchValidator(frm: FormGroup) {
  return frm.controls['password'].value === 
frm.controls['confirmpassword'].value ? null : {'mismatch': true};
}

Then you would define the validator without the this keyword:

{validator: passwordMatchValidator},

You can find the complete example here: https://github.com/DeborahK/Angular-ReactiveForms/tree/master/Demo-Final

Sign up to request clarification or add additional context in comments.

8 Comments

Just for my knowledge, is this is a right practice to put a validator on FormGroup level? As per my understanding, if there are many fields then it will create a performance issue. Because this will call every time, Please share your thoughts on alternates.
Personally, I create a new form group with only the two elements to validate and then attach the validator there. I'll update my answer with a link to the full code.
Based on your updated answer: One more new question arise. Say for example: In my form there are many fields which needs to be validate based on some other FormControl Values, Then Do I need to create seperate FormGroup for cross field validation of FormControl. Don't you think the code become clumsy, if I create a seperate FormGroup? Please let me know your views.
These types of decisions are impacted by so many factors, it is hard to say at which point it makes sense just to validate the entire form's group. Build it the way it makes sense and then look at whether there are performance issues you need to work on.
Now performance is not the issue based on your updated answer, but my question was: Is this is the right practice to create a separate FormGroup for every Cross-Field Validation? Don't you think the code become clumsy with your updated answer? Please share your inputs on respective questions. I am just curious about what are the other good alternatives to overcome this kind of problems.
|
3

For angular 8 you can use a custom validation like this.

Import the required libraries

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


const passwordErrorValidator: ValidatorFn = (control: FormGroup): ValidationErrors | null => {
  const password = control.get('a');
  const repeatPassword = control.get('b');
  return password.value != repeatPassword.value ? { 'passwordError': true } : null;
};

Init form like this

 heroForm = new FormGroup({   
    'a': new FormControl(),
    'b': new FormControl()
  }, { validators: passwordErrorValidator });

And in component

 <form [formGroup]="heroForm" (ngSubmit) ="createUser(heroForm.value)">
                <input id="a" name="a" class="form-control"
                required minlength="4"
                formControlName="a">
                <input id="b" name="b" class="form-control"
                required minlength="4"
                formControlName="b" >
                 <div *ngIf="heroForm.errors?.passwordError && (heroForm.touched || heroForm.dirty)" class="cross-validation-error-message alert alert-danger">
                  password mismatch
              </div>
              <input type="submit" class="btn btn-primary" value="Submit" />
            </form>

Comments

2

You can try this its working for me...

In your form

this.passwordForm = this.fb.group({
        newPassword: ['', [Validators.required, Validators.minLength(6)]],
        confirmNewPassword: ['', [Validators.required, Validators.minLength(6), (control => ValidationService.confirmPassword(control, this.passwordForm, 'newPassword'))]]
    });

ValidationService file

static confirmPassword(control: FormControl, group: FormGroup, matchPassword: string) {
    if (!control.value || group.controls[matchPassword].value !== null || group.controls[matchPassword].value === control.value) {
        return null;
    }
    return { 'mismatch': true }
}

Comments

1

finally i found my solution

export class ConfirmPasswordValidator {
    static MatchPassword(control: AbstractControl) {
       let password = control.get('password').value;

       let confirmpassword = control.get('confirmpassword').value;

        if(password != confirmpassword) {
            control.get('confirmpassword').setErrors( {ConfirmPassword: true} );
        } else {
            return null
        }
    }
}

Comments

-9

You can check form value of both like below.

<div class="error-msg" *ngIf="registerForm3.value.password !== registerForm3.value.confirmpassword">
    Passwords don't match.
</div>

2 Comments

This is not good practice. it will allow you to submit form even if password and confirm password are not matched.
@DevangMistry Then How do like you implement that?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.