1

I am trying to create a custom validator that will compare two passwords that should match, if they do not match a button should be disabled and if they do the user can complete registration.

After searching Stack Overflow, and looking through other sites I have rewritten the custom made validator to match previously provided answers; However, none of them seem to have any effect on the error I am encountering.

Imports

import { FormControl, Validators, FormGroup, ValidatorFn, AbstractControl } from "@angular/forms";
import { Component } from "@angular/core";
import { MatButton } from "@angular/material";

FormGroup

registerForm = new FormGroup({
    first: new FormControl(null, [
      Validators.required,
    ]),
    last: new FormControl(null, [
      Validators.required,
    ]),
    id: new FormControl(null, [
      Validators.required,
    ]),
    email: new FormControl(null, [
      Validators.required,
      Validators.email
    ]),
    newpass: new FormControl(null, [
      Validators.required,
      this.ageRangeValidator
    ]),
    confirmpass: new FormControl(null, [
      Validators.required,
      this.ageRangeValidator
    ]),
  }, {this.matchingPasswords} );

CustomValidator

matchingPasswords(c: AbstractControl): {[key: string]: any} {
    let password = c.get(['passwords']);
    let confirmPassword = c.get(['confirmpwd']);

    if (password.value !== confirmPassword.value) {
      return { mismatchedPasswords: true };
    }
    return null;
  }

As I attempt to run this code I run into the following error.

Argument of type '{ this: any; }' is not assignable to parameter of type 'ValidatorFn | ValidatorFn[] | AbstractControlOptions'. Object literal may only specify known properties, and 'this' does not exist in type 'ValidatorFn | ValidatorFn[] | AbstractControlOptions'.ts(2345)

This is for a school senior project.

halfer
  • 19,824
  • 17
  • 99
  • 186
Nick21
  • 13
  • 1
  • 3

2 Answers2

0

It appears the issue is with the call to

this.matchingPasswords

A validator needs to be a static function. So don't use the this keyword. You could define the matchingPasswords as a pure javascript function or you could define it as a static function in a typescript class(recommended approach). Then include the class in your module and pass the function as ClassName.matchingPasswords;

  • I've tried your solution, and the program successfully compiles without any errors; However, upon attempting to access the page you get a completely empty web page. Do you know why this might be, or what steps I should take to troubleshoot the issue? – Nick21 Apr 05 '19 at 19:33
  • Open developer tools in Google Chrome and check if you get any errors in the console. In developer tools you can look at the network tab as well to see what is being request and if those requests are getting responses. – Felix Friedman Apr 08 '19 at 13:08
0

You are returning null or a ValidatorError not only an object with an any property. Change the property type return of your matchingPasswords method:

matchingPasswords(c: AbstractControl): ValidationErrors | null {
    let password = c.get(['passwords']);
    let confirmPassword = c.get(['confirmpwd']);

    if (password.value !== confirmPassword.value) {
      return { mismatchedPasswords: true };
    }
    return null;
  }

For the html reference i would check if the control had any errors and validate whether that is due to the password not match instead being required:

<div *ngIf="registerForm.get('confirmpwd').errors && registerForm.get('confirmpwd').errors['mismatchedPasswords']">
   Passwords do not match
</div>
Tiago Silva
  • 2,299
  • 14
  • 18