Ionic 4 Form Validation Tutorial with Reactive Forms

By Digamber Rawat Last updated on
In this step by step Ionic 4 Forms validation tutorial, we will learn to create and validate a form with Angular’s Reactive Forms method.

Setting up forms in an Ionic application is easy, Angular offers Template-driven and Reactive Forms methods to deal with the forms data. Template-driven approach is used for working with simple forms. In contrast, It is used for handling more complex data. Especially when you need to work with nested values.

We will create a basic form with following input fields name, email, dob and mobile number.

Set Up Ionic Project

To setup a form in an Ionic app, you need to run the below command.

ionic start ionic-form-validation blank --type=angular

Get inside the project directory.

cd ionic-form-validation

Install lab mode as a dev-dependency by running the following command.

npm i @ionic/lab --save-dev

Start the Ionic app.

ionic serve -l

Ionic 4 Forms Project

Define Form Structure with Ionic HTML

To set up a form in Ionic use Ionic form UI components, below we are creating a form for school students and a student can fill information about himself using the form. We used Ionic’s checkboxes, radio buttons, buttons and other elements to build this form.

Open home.page.html file and add the following code inside of it.

<ion-content>
  <form>
    <ion-item lines="full">
      <ion-label position="floating">Name</ion-label>
      <ion-input type="text" required></ion-input>
    </ion-item>

    <ion-item lines="full">
      <ion-label position="floating">Email</ion-label>
      <ion-input type="email" required></ion-input>
    </ion-item>

    <ion-item lines="full">
      <ion-label position="floating">DOB</ion-label>
      <ion-input type="text" required></ion-input>
    </ion-item>

    <ion-item lines="full">
      <ion-label position="floating">Mobile</ion-label>
      <ion-input type="text" required></ion-input>
    </ion-item>

    <!-- Radio buttons -->
    <ion-radio-group lines="full">
      <ion-list-header>
        <ion-label>Gender</ion-label>
      </ion-list-header>

      <ion-item>
        <ion-label>Male</ion-label>
        <ion-radio slot="start" value="male" checked></ion-radio>
      </ion-item>

      <ion-item>
        <ion-label>Female</ion-label>
        <ion-radio slot="start" value="female"></ion-radio>
      </ion-item>
    </ion-radio-group>

    <!-- Checkboxes -->
    <ion-list lines="full">
      <ion-list-header>
        <ion-label>Subjects</ion-label>
      </ion-list-header>
      <ion-item>
        <ion-label>English</ion-label>
        <ion-checkbox></ion-checkbox>
      </ion-item>
      <ion-item>
        <ion-label>Maths</ion-label>
        <ion-checkbox></ion-checkbox>
      </ion-item>
      <ion-item>
        <ion-label>Science</ion-label>
        <ion-checkbox></ion-checkbox>
      </ion-item>
      <ion-item>
        <ion-label>History</ion-label>
        <ion-checkbox></ion-checkbox>
      </ion-item>
    </ion-list>

    <ion-row>
      <ion-col>
        <ion-button type="submit" color="danger" expand="block">Submit</ion-button>
      </ion-col>
    </ion-row>
  </form>
</ion-content>

Ionic 4 Forms Validation

Import & Register ReactiveFormsModule

To work with Reactive Forms we need to import and register ReactiveFormsModule. Now usually when we work with core Angular app so we declare ReactiveFormsModule globally in app.module.ts file. However, we have to declare ReactiveFormsModule in every page or component when we work with forms module.

Open home.module.ts and add the below code in it.

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { IonicModule } from '@ionic/angular';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { RouterModule } from '@angular/router';

import { HomePage } from './home.page';

@NgModule({
  imports: [
    CommonModule,
    ReactiveFormsModule,
    FormsModule,
    IonicModule,
    RouterModule.forChild([
      {
        path: '',
        component: HomePage
      }
    ])
  ],
  declarations: [HomePage]
})

export class HomePageModule { }

Creating Form in Ionic 4 with Reactive Forms

Next, we will use FormControl, FormGroup, FormBuilder, and Validators service to validate the form data.

Let’s understand what these services are?

FormGroup: A FormGroup is a collection of single or multiple FormControls and declared on the HTML’s form tag. Basically, its a collection of various form controls.

<form [formGroup]="ionicForm" (ngSubmit)="submitForm()" novalidate>
</form>

FormControl: A FormControl represents a value which is entered by the user, FormGroup is a collection of various FormControls.

<ion-content>
  <form [formGroup]="ionicForm" (ngSubmit)="submitForm()" novalidate>

    <ion-item lines="full">
      <ion-label position="floating">Name</ion-label>
      <ion-input formControlName="name" type="text" required></ion-input>
    </ion-item>

    <ion-item lines="full">
      <ion-label position="floating">Email</ion-label>
      <ion-input formControlName="email" type="email" required></ion-input>
    </ion-item>

    <ion-item lines="full">
      <ion-label position="floating">DOB</ion-label>
      <ion-datetime (ionChange)="getDate($event)" formControlName="dob" [value]="defaultDate"></ion-datetime>
    </ion-item>

    <ion-item lines="full">
      <ion-label position="floating">Mobile</ion-label>
      <ion-input formControlName="mobile" type="text" required></ion-input>
    </ion-item>

    <ion-row>
      <ion-col>
        <ion-button type="submit" color="danger" expand="block">Submit</ion-button>
      </ion-col>
    </ion-row>
  </form>
</ion-content>

FormBuilder: The FormBuilder service refers to a form object and sets up a FormGroup. It holds the user entered values and validation state of a form input field.

Import the following services to initialize the form in home.page.ts.

import { FormGroup, FormBuilder, Validators } from "@angular/forms";

Define the form object by declaring the FormGroup with a variable.

ionicForm: FormGroup;

Inject the FormBuilder service in the constructor.

constructor(public formBuilder: FormBuilder) { }

Setting up Date-picker in Ionic 4

Date-picker is used to get the date from the user, Ionic offers its own custom date-picker to deal with the date related date. We declared the date with ion-datetime tag in the HTML template. Now we will get the date value from the user and set in the dob formControl in Angular’s Reactive form.

We defined the defaultDate variable to set the default date. The getDate(e) function takes date object as an argument and convert it to YYYY-MM-DD format and set as a FormControl in the FormGroup.

getDate(e) {
   let date = new Date(e.target.value).toISOString().substring(0, 10);
   this.ionicForm.get('dob').setValue(date, {
      onlyself: true
   })
}

The (ngSubmit)="submitForm()" directive triggers a form submission.

submitForm() {
  console.log(this.ionicForm.value)
}

Enter some values in the form field and click on submit button, you will see user entered values in the ionicForm in the browser’s console.

Creating Form in Ionic 4

Validate Ionic 4 Form

In this section we will learn how to validate Ionic 4 form fields using Reactive Forms validators service.

Import Validators service to in the Ionic template, It provides built-in methods to validate form controls.

import { Validators } from "@angular/forms";

The Validators class offers following methods to deal with form validation in Ionic 4 / Angular 8.

class Validators {
  static min(min: number): ValidatorFn
  static max(max: number): ValidatorFn
  static required(control: AbstractControl): ValidationErrors | null
  static requiredTrue(control: AbstractControl): ValidationErrors | null
  static email(control: AbstractControl): ValidationErrors | null
  static minLength(minLength: number): ValidatorFn
  static maxLength(maxLength: number): ValidatorFn
  static pattern(pattern: string | RegExp): ValidatorFn
}

We will trigger the validation when user clicks on the submit button, so we need to define a boolean variable and set it to false initially.

isSubmitted = false;

Now, we will validate our name form control. In this value we will implement required and min-length validation.

this.ionicForm = this.formBuilder.group({
   name: ['', [Validators.required, Validators.minLength(2)]],
})

As you can see we injected the validation methods with the help of Validators class. Validators array allow us to implement multiple validation in a single form control.

Now, we will declare the getter method to access the form control. Add the following code to access the form control directly via the Ionic / Angular template.

get errorControl() {
  return this.ionicForm.controls;
}

Next, we need to add the alert messages in the Ionic’s HTML template for showing the validation messages. These, messages will appear when the form is invalid.

<form [formGroup]="ionicForm" (ngSubmit)="submitForm()" novalidate>
  <ion-item lines="full">
    <ion-label position="floating">Name</ion-label>
    <ion-input formControlName="name" type="text"></ion-input>
  </ion-item>

  <!-- Error messages -->
  <span class="error ion-padding" *ngIf="isSubmitted && errorControl.name.errors?.required">
    Name is required.
  </span>
  <span class="error ion-padding" *ngIf="isSubmitted && errorControl.name.errors?.minlength">
    Name should be min 2 chars long.
  </span>
</form>

Inside the *ngIf directive, we are checking if both the conditions are true. The *ngIf="" directive will only show the alert message to the users when the form is invalid.

Following method will trigger the form on submit.

submitForm() {
  this.isSubmitted = true;
  if (!this.ionicForm.valid) {
    console.log('Please provide all the required values!')
    return false;
  } else {
    console.log(this.ionicForm.value)
  }
}

Here are the final code of this Ionic 4/Angular 8 Form validation tutorial.

home.page.ts
import { Component, OnInit } from '@angular/core';
import { FormGroup, FormBuilder, Validators } from "@angular/forms";

@Component({
  selector: 'app-home',
  templateUrl: 'home.page.html',
  styleUrls: ['home.page.scss'],
})

export class HomePage implements OnInit {
  ionicForm: FormGroup;
  defaultDate = "1987-06-30";
  isSubmitted = false;

  constructor(public formBuilder: FormBuilder) { }

  ngOnInit() {
    this.ionicForm = this.formBuilder.group({
      name: ['', [Validators.required, Validators.minLength(2)]],
      email: ['', [Validators.required, Validators.pattern('[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,3}$')]],
      dob: [this.defaultDate],
      mobile: ['', [Validators.required, Validators.pattern('^[0-9]+$')]]
    })
  }

  getDate(e) {
    let date = new Date(e.target.value).toISOString().substring(0, 10);
    this.ionicForm.get('dob').setValue(date, {
      onlyself: true
    })
  }

  get errorControl() {
    return this.ionicForm.controls;
  }

  submitForm() {
    this.isSubmitted = true;
    if (!this.ionicForm.valid) {
      console.log('Please provide all the required values!')
      return false;
    } else {
      console.log(this.ionicForm.value)
    }
  }
}
home.page.html
<ion-header>
  <ion-toolbar>
    <ion-title>Ionic Forms</ion-title>
  </ion-toolbar>
</ion-header>

<ion-content>
  <form [formGroup]="ionicForm" (ngSubmit)="submitForm()" novalidate>

    <ion-item lines="full">
      <ion-label position="floating">Name</ion-label>
      <ion-input formControlName="name" type="text"></ion-input>
    </ion-item>
    <span class="error ion-padding" *ngIf="isSubmitted && errorControl.name.errors?.required">
      Name is required.
    </span>
    <span class="error ion-padding" *ngIf="isSubmitted && errorControl.name.errors?.minlength">
      Name should be min 2 chars long.
    </span>

    <ion-item lines="full">
      <ion-label position="floating">Email</ion-label>
      <ion-input formControlName="email" type="email"></ion-input>
    </ion-item>
    <span class="error ion-padding" *ngIf="isSubmitted && errorControl.email.errors?.required">
      Email is required.
    </span>
    <span class="error ion-padding" *ngIf="isSubmitted && errorControl.email.errors?.pattern">
      Please provide valid email id.
    </span>

    <ion-item lines="full">
      <ion-label position="floating">DOB</ion-label>
      <ion-datetime (ionChange)="getDate($event)" formControlName="dob" [value]="defaultDate"></ion-datetime>
    </ion-item>

    <ion-item lines="full">
      <ion-label position="floating">Mobile</ion-label>
      <ion-input maxlength="10" formControlName="mobile" type="text" required></ion-input>
    </ion-item>
    <span class="error ion-padding" *ngIf="isSubmitted && errorControl.mobile.errors?.required">
      Mobile number is required.
    </span>
    <span class="error ion-padding" *ngIf="isSubmitted && errorControl.mobile.errors?.pattern">
      Only numerical values allowed.
    </span>

    <ion-row>
      <ion-col>
        <ion-button type="submit" color="danger" expand="block">Submit</ion-button>
      </ion-col>
    </ion-row>
  </form>
</ion-content>

Validate Ionic 4 Form

Conclusion

Finally, we have finished Ionic 4 Form Validation Tutorial with Reactive Forms. We just learned the basic form validation with Reactive Forms in Ionic 4 app, I hope you will surely liked it.

Digamber Rawat
Digamber Rawat

Full stack developer with a passion for UI/UX design. I create beautiful and useful digital products to solve people’s problem and make their life easy.

Thanks for checking this tutorial out :) Let me know if you have any suggestions or issue related to this tutorial, or you want to request a new tutorial. Just shoot me a mail here.