1

I can't get my *ngIf to show up if passwords don't match.

<md-form-field>
    <input mdInput placeholder="Repeat password" type="password" formControlName="repeat">
    <md-error *ngIf="form.controls['repeat'].errors?.required">Field required</md-error>
    <md-error *ngIf="form.errors?.matchingPasswords">passwords don't match</md-error>
</md-form-field>

Here's my constructor

  constructor(private formBuilder: FormBuilder) {
    this.form = this.formBuilder.group({
      username:
      ['',
        Validators.compose([
          Validators.required,
          Validators.minLength(3),
          Validators.maxLength(30),
          this.validateUsername,
          this.validateUsernameAvailability
        ])
      ],
      email:
      ['',
        Validators.compose([
          Validators.required,
          Validators.maxLength(30),
          this.validateEmail
        ])
      ],
      password:
      ['',
        Validators.compose([
          Validators.required,
          Validators.minLength(8),
          Validators.maxLength(30),
          this.validatePassword
        ])
      ],
      repeat: ['',
        Validators.compose([
          Validators.required
        ])
      ]
    }, {validator: this.matchingPasswords('password', 'repeat')});
  }

  matchingPasswords(password, repeat) {
    return (group: FormGroup) => {
      // Check if both fields are the same
      if (group.controls[password].value === group.controls[repeat].value) {
        return null; // Return as a match
      } else {
        return { 'matchingPasswords': true }; // Return as error: do not match
      }
    };
  }

Here's a screenshot

@EDIT Using a simple <span> instead of <md-error> seems to fix it.

<span *ngIf="form.errors?.matchingPasswords">passwords don't match</span>

But why doesn't the <md-error> show up?

1 Answer 1

1

Seems to be a 'bug' that needs a workaround.

md-error inside md-form-field just validates that specific input, taking no regard to any other inputs. So if you move that outside the md-form-field it will validate, but of course the css will be messed up in that case. The a fix is to use md-hint instead and just modify that with css to emulate the md-error:

<md-hint *ngIf="form.errors?.matchingPasswords">passwords don't match</md-hint>

Just to throw it out there you could skip the custom validator and use Custom Error Matcher like so:

myErrorStateMatcher(control: FormControl): boolean {
  if(control.parent.controls.password.value === control.value) {
    control.setErrors(null)
    return false;
  }
  else {
    control.setErrors({notSame:true})
    return true;
  }
}

in template:

<input mdInput formControlName="repeat" [errorStateMatcher]="myErrorStateMatcher">

DEMO

But with this you really have no control of when this is fired. Though with the code you have currently your custom validator is also fired whenever any change is happening to form. With that, check the sidenotes below.


Sidenotes:

If going with md-hint I'd wrap the password and repeat inside a nested form group and apply the custom validator to that nested form group, so that it's only fired when changes happen to either of those two form controls.

As for the repeat form control, I see no need to use any other validation, than to check if it matches the password field.

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

Comments

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.