Ionic 4 | How To Create And Validate Forms

Written by on July 1, 2019

Ionic 4 | How To Create And Validate Forms

I developed this article to demonstrate to you how your Ionic 4 application can manage form validation. This is the fourth iteration of this article since the introduction of Ionic 2 and I hope I won’t need to update in the near future.

What I am going to give here is a fast illustration of how to use Reactive forms to set up form validation in Angular 8 and Ionic 4. Below example is a simple authentication form with standard fields like email and password. If you would like to see a more complex example, leave me a comment below and I can do it in a day or two.

Note: If this tutorial was helpful, you need further clarification, something is not working or you have a request for another Ionic post? Furthermore, leave me a comment below if you don't like something about this blog, if something is bugging you, don't like how I'm doing stuff here. Feel free to comment below, subscribe to my blog, mail me to Thanks and have a nice day!


If you are looking for a better example of form validation look at the below link Working Authentication Example. It uses this example and builds upon it.


As in all my other tutorials on this topic, you need to have a working Ionic 4 workspace.

You will need these to finish your tutorial:

  • Android or iOS environment (optional as we can also run it in our browser)
  • NodeJS
  • Ionic
  • Cordova

If you neet to set-up a working Ionic 4 environment just follow this tutorial: Ionic [2|3] | Installation Guide.

1. Update Ionic CLI

Install or update your current Ionic version:

npm install -g ionic cordova

To update:

npm update -g ionic cordova

2. Create A New Project

ionic start IonicFormValidationV2 blank
cd IonicFormValidationV2

You will find a working example at the end of this article, or keep reading if you are interested in how it works. Jump to the working example here.

Warning: As some of you don't have a prior Ionic CLI experience, from this point and on, every time I tell you to execute something, do that inside an example project folder.

3. Add Required Platform

If you want to use the browser:

ionic cordova platform add browser

Android platform:

ionic cordova platform add android

iOS platform:

ionic cordova platform add ios

Source Walkthrough

The main idea is to make this tutorial as easy as possible.

As this is an authentication example we will need two pages: auth and home. Auth page will hold our form while home page will just hold a welcoming message.

Let’s start by adding the auth page, the home page will already be there.

ionic g page pages/auth

This will generate a new folder called auth (inside pages folder) including our new AuthPage page. This process works automatically and the AuthPage name is a combination of a page name we provided with ionic generate command. You can also do this manually but this way is much faster and error free.

At this point, we have a simple app with two distinct pages. Let’s proceed to app-routing.module.ts file and update existing Angular routing use auth as the initial page.

const routes: Routes = [
  { path: '', redirectTo: 'auth', pathMatch: 'full' },
  { path: 'auth', loadChildren: './pages/auth/auth.module#AuthPageModule' },
  { path: 'home', loadChildren: './pages/home/home.module#HomePageModule' },

Open auth.ts page as we will spend the most of our time there.

To be able to work with Angular Reactive forms we first need to import them:

import { Router } from '@angular/router';
import { FormBuilder, FormGroup, Validators, ReactiveFormsModule } from '@angular/forms';

I have also imported routing as we will need it to change a page.

  • While we can build forms using ngForm and ngControl, a more flexible way is using FormBuilder. It’s just a helper service (class) that helps us build forms using Control object.
  • A single Control object represents a single form item.

For our example, we will use two distinctive input boxes and one submit button.

	<ion-label>User Name (Email)</ion-label>
	<ion-input formControlName="email"></ion-input>

	<ion-input formControlName="password"></ion-input>

			<ion-button expand="block" size="large" type="submit">Authenticate</ion-button>    
			<ion-button expand="block" size="large" type="reset" (click)="onReset()">Reset</ion-button> 

Take a careful look at each input field, you’ll notice a special keyword called formControlName:

<ion-input formControlName="email"></ion-input>

This keyword defines a Control object (a single form field).

Both email and password are defined as a part of FormBuilder group:

this.authForm ={
	email: ['', [Validators.required,]],
	password: ['', [Validators.required, Validators.minLength(6)]]
}, {});

This is also how we are initializing the form.

We will also need to access our form directly:

<form [formGroup]="authForm" (ngSubmit)="onSubmit(authForm.value)">	

We are doing it using FormGroup keyword in both and

authForm: FormGroup;	

We’re using FormBuilder helper service formBuilder to group form fields into ControlGroup object called authForm.

Let’s play with validations:

email: ['', [Validators.required,]],
password: ['', [Validators.required, Validators.minLength(6)]]

All the above validations are prebuilt in Angular; you can find many more in the official Angular documentation.

<div *ngIf="submitted &&" class="invalid-feedback">
	<ion-item *ngIf="">
		<p style="color:red">Email is required!</p>
	<ion-item *ngIf="">
		<p style="color:red">Email must be a valid email address!</p>

If the form was submitted but the validation process was not successful, our application will show above warning messages.

To make this easy, I have shortened a way we are accessing form elements. Look here:

<ion-item *ngIf="">

The usual way would be to write it like this:

<ion-item *ngIf="">

However, the code can get unreadable very quickly when complex forms are used.

In our case, I have replaced authForm.controls with the function frm. If you look at you will find this function used for this ​substitution:

get frm() { return this.authForm.controls; } 	
Continue to the next page


51 thoughts on “Ionic 4 | How To Create And Validate Forms”

  1. Thanks for that. This helped me a lot.

    I managed to get rid of the ‘function’ keyword in
    checkFirstCharacterValidator(control: Control): { [s: string]: boolean } { … }

    by adding ‘this’ in the Validators group:
    ‘username’: [”, Validators.compose([Validators.required, Validators.minLength(8), this.checkFirstCharacterValidator])],

    I also didn’t need to add the class declarations as they are already declared in the constructor:
    //authForm: ControlGroup;
    //username: AbstractControl;
    //password: AbstractControl;

    Lastly I changed the return line from the checkFirstCharacterValidator function to:
    return {“invalid_firstCharacter”: true};
    as I found naming the string and the method the same confusing (even though that’s what the native angular 2 validator functions do).

  2. One of the things i don’t like about ionic 2 is the import part… you need to import a lot of things, when you only want to do something really simple. How can i remember this? i have to come back to this article every time.

  3. Hi,
    Thanks for your share !
    I’m very newbie on ionic.
    However, I’ve a trouble : I’ve copy/paste your code for testing and I’ve compilation parsing error on three variables declaration (authForm, username and password).
    It seems does not accept variable declaration on class and I don’t know why.
    Could you help me ?


  5. HI! I’m trying to follow your guide, but there’s no way i can make the custom Validator Work :/
    I wrote a console.log() in the validator, but it never appears, like it’s never called! Would you please paste your whole CustomValidator.ts file? Thanks!

    • Just download my GitHub example, you can find it on the second page. Though I will also add CustomValidator.ts, I forgot to add it after my last article update.

      • After having a look at the required validator I realised that the logic of the custom validator function had to be inverted. If (valid) return null else return {‘required’: true}

  6. Hi, Thanks for your post. It’s really helped a lot. Please help me to add validation for creating dynamic elements. i’m trying to add validation for input elements using ng-repeat.

    • Yes think so. beta11 is now using the new angular forms.
      think you use some setting in ionicBootstrap to use the old forms but not really the way forward.

  7. hey i am not able to submit the form,when i click on submit there is no submitted values shown in the console

  8. How to prevent hidden field validation. In my form i have a select box, if i select one option some fields are visible, if select another option then other fields are visible and the previous fields are hidden.

  9. hi, thanks for the great post
    any upcoming update for the post
    also how can I validate for retype password ??

  10. Thanks for the article.
    I get this error:
    “Can’t bind to ‘ngFormModel’ since it isn’t a known native property”

    I use beta.11

  11. Unfortunately doesn’t work in beta 11 – “ORIGINAL EXCEPTION: No value accessor for ””

  12. Hi, Thanks for effort, the only problem is ionic2 and angular2 have had a lot of breaking changes, also the article doesn’t have published date (or mentioning ionic2 and angular2 version that this is based on), then it will be so confusing.

  13. Thank you so much.This is working fine..particular working in latest ionic 2 version and angular 2 rc versions. Thank you once again .@gajotres

  14. In above form how to display variable value in username field– I have {{username}} containing user name.. I want to display that value in username field..

  15. Is it possible to create multiple inputs dynamically and use the same formControlnames for them? For example, I am doing a create group form with a dynamic number of possible group members that the user can change by hitting the ‘add member’ button. I want to make sure the form is validated the same way for each respective member object and its fields as well as the overlying group name, description etc. Any way to do this?

Leave a Reply