3d cartoon hands holding a phone

Unlock full course by purchasing a membership

Lesson 10

Form Validation and User Experience

Improving our login and create account forms

EXTENDED

Form Validation and User Experience

In this lesson, we are going to focus on improving the user experience of our two forms by improving how we handle validations. We already have some basic validations in place, but we will be aiming to:

  • Display clear validation errors to the user at the appropriate time
  • Create a custom validator to check that the password and confirmPassword fields match

Create a Confirm Password Validator

This is something we have already covered conceptually in the module on form validators - so if the exact implementation is a little unclear here it might be worth going back to that module.

Create a new file at src/app/create/utils/password-matches.ts and add the following:

import { AbstractControl, ValidationErrors, ValidatorFn } from '@angular/forms';

export const passwordMatchesValidator: ValidatorFn = (
  control: AbstractControl
): ValidationErrors | null => {
  const password = control.get('password')?.value;
  const confirmPassword = control.get('confirmPassword')?.value;

  return password && confirmPassword && password === confirmPassword
    ? null
    : { passwordMatch: true };
};

Add the validator to the CreateFormComponent:

  createForm = this.fb.nonNullable.group(
    {
      email: ['', [Validators.email, Validators.required]],
      password: ['', [Validators.minLength(8), Validators.required]],
      confirmPassword: ['', [Validators.required]],
    },
    {
      updateOn: 'blur',
      validators: [passwordMatchesValidator],
    }
  );

Add Validator Error Messages

We are also going to use the same concept we discussed in the advanced forms module here for validator error messages. What we want to do is:

  • Not immediately show error messages
  • Show an error message if a control is invalid and the user has interacted with the control
  • Show an error message if a control is invalid and the form has been submitted
  • Show an error message for the status state (i.e. if the login/create account operation fails)

Update the template for the CreateFormComponent to reflect the following:

    <form [formGroup]="createForm" (ngSubmit)="onSubmit()" #form="ngForm">
      <ion-item lines="none">
        <ion-icon color="light" slot="start" name="mail-outline"></ion-icon>
        <ion-input
          formControlName="email"
          type="email"
          placeholder="email"
        ></ion-input>
      </ion-item>
      <ion-note
        color="danger"
        *ngIf="
          (createForm.controls.email.dirty || form.submitted) &&
          !createForm.controls.email.valid
        "
      >
        Please provide a valid email
      </ion-note>
      <ion-item lines="none">
        <ion-icon
          color="light"
          slot="start"
          name="lock-closed-outline"
        ></ion-icon>
        <ion-input
          formControlName="password"
          type="password"
          placeholder="password"
        ></ion-input>
      </ion-item>
      <ion-note
        color="danger"
        *ngIf="
          (createForm.controls.password.dirty || form.submitted) &&
          !createForm.controls.password.valid
        "
      >
        Password must be at least 8 characters long
      </ion-note>
      <ion-item lines="none">
        <ion-icon
          color="light"
          slot="start"
          name="lock-closed-outline"
        ></ion-icon>
        <ion-input
          formControlName="confirmPassword"
          type="password"
          placeholder="confirm password"
        ></ion-input>
      </ion-item>
      <ion-note
        color="danger"
        *ngIf="
          (createForm.controls.confirmPassword.dirty || form.submitted) &&
          createForm.hasError('passwordMatch')
        "
      >
        Must match password field
      </ion-note>
      <ion-note color="danger" *ngIf="createStatus === 'error'">
        Could not create account with those details.
      </ion-note>
      <ion-button
        type="submit"
        expand="full"
        [disabled]="createStatus === 'creating'"
      >
        <ion-spinner *ngIf="createStatus === 'creating'"></ion-spinner>
        Submit
      </ion-button>
    </form>
EXTENDED
Key

Thanks for checking out the preview of this lesson!

You do not have the appropriate membership to view the full lesson. If you would like full access to this module you can view membership options (or log in if you are already have an appropriate membership).