password and confirm password field validation ang

2019-01-04 13:25发布

I need to check whether password and confirm password fields have same value using reactive form angular2. I did see a lot of answers on the same here,Angular 2 form validating for repeat password ,Comparing fields in validator with angular2, but none seemed to work for me.Can someone please help."this" is undefined in my validate function :( . Sharing my code,

this.addEditUserForm = this.builder.group({
            firstName: ['', Validators.required],
            lastName: ['', Validators.required],
            title: ['', Validators.required],
            email: ['', Validators.required],
            password: ['', Validators.required],
            confirmPass: ['', [Validators.required, this.validatePasswordConfirmation]]
        });
validatePasswordConfirmation(group: FormGroup): any{
        let valid = true;
        // if (this.addEditUserForm.controls.password != this.addEditUserForm.controls.confirmPass) {
        //     valid = false;
        //     this.addEditUserForm.controls.confirmPass.setErrors({validatePasswordConfirmation: true});
        // }
        return valid;
    }

5条回答
爷、活的狠高调
2楼-- · 2019-01-04 13:33

This is what eventually worked for me -

this.addEditUserForm = this.builder.group({
            firstName: ['', Validators.required],
            lastName: ['', Validators.required],
            title: ['', Validators.required],
            email: ['', Validators.required],
            password: ['', Validators.required],
            confirmPass: ['', Validators.required]
        },{validator: this.checkIfMatchingPasswords('password', 'confirmPass')});



checkIfMatchingPasswords(passwordKey: string, passwordConfirmationKey: string) {
          return (group: FormGroup) => {
            let passwordInput = group.controls[passwordKey],
                passwordConfirmationInput = group.controls[passwordConfirmationKey];
            if (passwordInput.value !== passwordConfirmationInput.value) {
              return passwordConfirmationInput.setErrors({notEquivalent: true})
            }
            else {
                return passwordConfirmationInput.setErrors(null);
            }
          }
        }
查看更多
SAY GOODBYE
3楼-- · 2019-01-04 13:37

Best would be to have a nested group inside the form group, where we have a custom validator checking the form group with password and confirmPass, so when either of the fields are changed, the validator is fired, as of previously it only fires when confirmPass field is modified.

So instead do something like this inside the outer formgroup:

// ...
passwords: this.fb.group({
  password: ['', [...]],
  confirmPass: ['', [...]]
}, {validator: this.checkPasswords}) // add a validator for the whole group
// ...

and then the validator could look like this:

checkPasswords(group: FormGroup) { // here we have the 'passwords' group
  let pass = group.get('password').value;
  let confirmPass = group.get('confirmPass').value;

  return pass === confirmPass ? null : { notSame: true }     
}

Showing the validation error could then be done like this:

*ngIf="addEditUserForm.hasError('notSame', 'passwords')"

Of course you don't need to have a nested group, but it's better to not have the custom validator fire every time when any changes happen to the form. This way it's only fired when changes happen to this inner form group.

查看更多
可以哭但决不认输i
4楼-- · 2019-01-04 13:44

If you want to do it that way, you need bind the function to the current "this" context. Pass over this.validatePasswordConfirmation.bind(this) but note that this function will be passed the FormControl for the confirmation, and not the FormGroup like you stated in the function signature.

查看更多
我命由我不由天
5楼-- · 2019-01-04 13:49

I did a different approach that will work for any control. First I define the basic controls of the form:

    this.myForm = this.formBuilder.group({
            name: ['', Validators.required],
            password: ['', Validators.required],
    });

Then I create a new control to confirm the value with my custom validator:

    const confirmPasswordControl = new FormControl('', {
            validator: sameValueAs(this.myForm, 'password')
    });

    this.myForm.addControl('confirmPassword', confirmPasswordControl);

The code of the sameValueAs validator is as follows, you can define it on a separte file to be used anywhere

export function sameValueAs(group: FormGroup, controlName: string): ValidatorFn {
    return (control: FormControl) => {
          const myValue = control.value;
          const compareValue = group.controls[controlName].value;

          return (myValue === compareValue) ? null : {valueDifferentFrom:controlName};

    };
}
查看更多
兄弟一词,经得起流年.
6楼-- · 2019-01-04 13:56

If you don't want to go through a custom validator you can just create a input field that is standalone and therefore will not compute in your formGroup but rather through ngModel

<input type="password" matInput [(ngModel)]="passwordConfirm" [ngModelOptions]="{standalone: true}">

Then in your ts you can just validate and throw error or invalidate the form if you want. Just found it slightly quicker and practical:

// Check Passwords Match

  if (this.staffAccountForm.value.password !== this.passwordConfirm) {
    this.snackbar.snackBarSimple('Passwords do not match.');
    return false;
  }
查看更多
登录 后发表回答