Ionic form validation not working

Hi,

In my ionic project reactive forms are not working. Ideally when user enters a wrog value, it should display erroe message immediately but it do not. I could not figure our where the problem is and need some help.

I am using Ionic version 5.2.3 and npm version 6.9.0

Here is the code

import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators, FormControl, ReactiveFormsModule } from '@angular/forms';

@Component({
  selector: 'app-register',
  templateUrl: './register.page.html',
  styleUrls: ['./register.page.scss'],
})
export class RegisterPage implements OnInit {
  fg: FormGroup;

  constructor(public fb: FormBuilder) { }

  ngOnInit() {
    this.fg = this.fb.group({
      emailControl: new FormControl('', Validators.required),
      passwordControl: new FormControl('', Validators.required),
      confirmControl: new FormControl('', Validators.required),
      mobileControl: new FormControl('', Validators.required),
      add1Control: new FormControl(''),
      add2COntrol: new FormControl(''),
      postcodeControl: new FormControl(''),
      stateControl: new FormControl('')
    });
  }

  onSubmit(values) {
    console.log(values);
  }
}

The UI code is here

<ion-content>
  <form [attr.formGroup]="fg" (ngSubmit)="onSubmit(fg.value)">
      <ion-list lines="full" class="ion-no-margin ion-no-padding">
          <ion-item>
              <ion-label position="stacked">Email Address*</ion-label>
              <p>
                <!-- <ion-input type = "email"  placeholder="Register - Enter valid email address"></ion-input> -->
                <ion-input type = "email"  attr.formControlName="emailControl" required></ion-input>
              </p>
            </ion-item>
            <ion-item>
              <div *ngIf="fg.get('emailControl').invalid">
              <!--     <div > -->
                  <ion-label position="stacked">{{ fg.get('emailControl').invalid }} {{ fg.get('emailControl').dirty}} {{ fg.get('emailControl').touched}}</ion-label>
              </div>
            </ion-item>
            <ion-item>
              <ion-label position="stacked">Password*</ion-label>
              <p>
                <ion-input type = "password" attr.formArrayName="passwordControl" required placeholder="Enter password"></ion-input>
                <!-- <ion-input type = "password" formArrayName="passwordControl" placeholder="Enter password"></ion-input> -->
              </p>
            </ion-item>
            <ion-item>
              <ion-label position="stacked">confirm Password*</ion-label>
              <p><ion-input type = "password" attr.formControlName="confirmControl" required placeholder="Confirm password"></ion-input></p>
            </ion-item>
            <ion-item>
              <ion-label position="stacked">Mobile Number*</ion-label>
              <p><ion-input type = "number" attr.formControlName="mobileControl" placeholder="Enter mobile number"></ion-input></p>
            </ion-item>
            <ion-item>
              <ion-label position="stacked">Address</ion-label>
              <p><ion-input type = "text" attr.formControlName="add1Control" placeholder="Address Lin 1"></ion-input>
              <ion-input type = "text" attr.formControlName="add2Control" placeholder="Address Lin 2"></ion-input>
              <ion-input type = "text" attr.formControlName="postcodeControl" placeholder="Postcode"></ion-input>
              <ion-input type = "text" attr.formControlName="stateControl" placeholder="State"></ion-input></p>
            </ion-item>
            <ion-item>
              <ion-button type="submit" color="success" expand="full">Register</ion-button>
              <p></p>
            </ion-item>
            <ion-item>
             <ion-label position="stacked">Message here</ion-label>
            </ion-item>
      </ion-list>
    </form>
</ion-content>

Module.ts is as below

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

import { IonicModule } from '@ionic/angular';

import { RegisterPage } from './register.page';

const routes: Routes = [
  {
    path: '',
    component: RegisterPage
  }
];

@NgModule({
  imports: [
    CommonModule,
    FormsModule,
    ReactiveFormsModule,
    IonicModule,
    RouterModule.forChild(routes)
  ],
  declarations: [RegisterPage]
})
export class RegisterPageModule {}

I have seen many online documentation and examples but could not figure out where the problem is. ANy help will be highly appreciated.

Hello, Here working code:

page.ts

import { Component } from '@angular/core';
import { FormBuilder, FormGroup, Validators, FormControl } from '@angular/forms';

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

  public myform: FormGroup;
  public errorMessage: string = '';

  form_messages = {
    'email': [
      { type: 'required', message: 'Email is required.' },
    ],
    'password': [
      { type: 'required', message: 'Password is required.' },
    ],
    'confpass': [
      { type: 'required', message: 'Confirm password is required.' },
    ],
    'number': [
      { type: 'required', message: 'Mobile number is required.' },
    ]
  };

  constructor(public formBuilder: FormBuilder) { }

  ngOnInit() {
    this.myform = this.formBuilder.group({
      email: new FormControl('', Validators.required),
      password: new FormControl('', Validators.required),
      confpass: new FormControl('', Validators.required),
      number: new FormControl('', Validators.required),
      add1: new FormControl(''),
      add2: new FormControl(''),
      postcode: new FormControl(''),
      state: new FormControl('')
    });
  }

  onSubmit(values: any) {
    console.log(values);
  }

}

page.html

<ion-content>
  <form [formGroup]="myform" (ngSubmit)="onSubmit(myform.value)">
    <ion-list lines="full" class="ion-no-margin ion-no-padding">
      <ion-item>
        <ion-label position="stacked">Email Address<span class="require">*</span></ion-label>
        <ion-input type="email" formControlName="email" required></ion-input>
      </ion-item>
      <div class="validation-errors">
        <ng-container *ngFor="let validation of form_messages.email">
          <div class="error-message"
            *ngIf="myform.get('email').hasError(validation.type) && (myform.get('email').dirty || myform.get('email').touched)">
            {{ validation.message }}
          </div>
        </ng-container>
      </div>
      <ion-item>
        <ion-label position="stacked">Password<span class="require">*</span></ion-label>
        <ion-input type="password" formControlName="password" required placeholder="Enter password">
        </ion-input>
      </ion-item>
      <div class="validation-errors">
        <ng-container *ngFor="let validation of form_messages.password">
          <div class="error-message"
            *ngIf="myform.get('password').hasError(validation.type) && (myform.get('password').dirty || myform.get('password').touched)">
            {{ validation.message }}
          </div>
        </ng-container>
      </div>
      <ion-item>
        <ion-label position="stacked">confirm Password<span class="require">*</span></ion-label>
        <ion-input type="password" formControlName="confpass" required placeholder="Confirm password">
        </ion-input>
      </ion-item>
      <div class="validation-errors">
        <ng-container *ngFor="let validation of form_messages.confpass">
          <div class="error-message"
            *ngIf="myform.get('confpass').hasError(validation.type) && (myform.get('confpass').dirty || myform.get('confpass').touched)">
            {{ validation.message }}
          </div>
        </ng-container>
      </div>
      <ion-item>
        <ion-label position="stacked">Mobile Number<span class="require">*</span></ion-label>
        <ion-input type="number" formControlName="number" placeholder="Enter mobile number"></ion-input>
      </ion-item>
      <div class="validation-errors">
        <ng-container *ngFor="let validation of form_messages.number">
          <div class="error-message"
            *ngIf="myform.get('number').hasError(validation.type) && (myform.get('number').dirty || myform.get('number').touched)">
            {{ validation.message }}
          </div>
        </ng-container>
      </div>
      <ion-item>
        <ion-label position="stacked">Address</ion-label>
        <ion-input type="text" formControlName="add1" placeholder="Address Lin 1"></ion-input>
        <ion-input type="text" formControlName="add2" placeholder="Address Lin 2"></ion-input>
        <ion-input type="text" formControlName="postcode" placeholder="Postcode"></ion-input>
        <ion-input type="text" formControlName="state" placeholder="State"></ion-input>
      </ion-item>
      <ion-item>
        <ion-button type="submit" color="success" expand="full">Register</ion-button>
      </ion-item>
      <ion-item>
        <ion-label position="stacked">Message here</ion-label>
      </ion-item>
    </ion-list>
  </form>
</ion-content>

page.scss

.require {
  color: rgb(241, 1, 1);
}

.error-message {
  font-size: smaller;
  padding-left: 15px;
}

page.module.ts

.....
import { ReactiveFormsModule } from '@angular/forms';
.....

imports: [ReactiveFormsModule]

let me know it won’t work

1 Like

hey gokujy,

Many thanks for sharing this. It worked. Thanks a lot.