Skip to content

Validators (FormGroup)

Joan Pablo edited this page Oct 18, 2020 · 3 revisions

There are special validators that can be attached to FormGroup. In the next section we will see an example of that.

What about Password and Password Confirmation?

There are some cases where we want to implement a Form where a validation of a field depends on the value of another field. For example a sign-up form with email and emailConfirmation or password and passwordConfirmation.

For that cases we must implement a custom validator and attach it to the FormGroup, lets see an example:

final form = FormGroup({
  'name': FormControl(validators: [Validators.required]),
  'email': FormControl(validators: [Validators.required, Validators.email]),
  'password': FormControl(validators: [
    Validators.required,
    Validators.minLength(8),
  ]),
  'passwordConfirmation': FormControl(),
}, validators: [
  _mustMatch('password', 'passwordConfirmation')
]);

Notice the use of Validators.minLength(8)

In the previous code we have added two more fields to the form: password and passwordConfirmation, both fields are required and the password must be at least 8 characters length.

However the most important thing here is that we have attached a validator to the FormGroup. This validator is a custom validator and the implementation follows as:

ValidatorFunction _mustMatch(String controlName, String matchingControlName) {
  return (AbstractControl control) {
    final form = control as FormGroup;

    final formControl = form.control(controlName);
    final matchingFormControl = form.control(matchingControlName);

    if (formControl.value != matchingFormControl.value) {
      matchingFormControl.setErrors({'mustMatch': true});

      // force messages to show up as soon as possible
      matchingFormControl.markAsTouched(); 
    } else {
      matchingFormControl.setErrors({});
    }

    return null;
  };
}

Fortunately you don't have to implement a custom must match validator because we have already included it into the code of the reactive_forms package so you could reuse it. The previous form definition example will become into:

final form = FormGroup({
  'name': FormControl(validators: [Validators.required]),
  'email': FormControl(validators: [Validators.required, Validators.email]),
  'emailConfirmation': FormControl(),
  'password': FormControl(validators: [
    Validators.required,
    Validators.minLength(8),
  ]),
  'passwordConfirmation': FormControl(),
}, validators: [
  Validators.mustMatch('email', 'emailConfirmation'),
  Validators.mustMatch('password', 'passwordConfirmation'),
]);
Clone this wiki locally