-1

I am working on a project which uses the latest version of Angular and Ionic. I am working on a registration page. I need to display some error when the form input is not valid. I am using Angular Reactive form in my project but if I check error on the page it is not displayed. It only shows red color underline but I need to show some readable errors

enter image description here

Here is my View code

<ion-content padding>
  <ion-list class="items-middle" text-center>
    <!-- use the [formGroup] directive to tell Angular that we want to use the registrationForm as the "FormGroup" for this form: -->
    <form [formGroup]="registrationForm">
      <ion-item>
        <ion-label floating>Full Name</ion-label>
        <ion-input type="text" formControlName="userName"></ion-input>
        <div *ngIf="!registrationForm.controls['userName'].valid && registrationForm.controls['userName'].touched"> name is required</div>
      </ion-item>
      <!-- <ion-item>
                <ion-label color="ligh-grey" floating>Email</ion-label>
                <ion-input type="email" formControlName="email"></ion-input>
            </ion-item>
            <ion-item>
                <ion-label color="ligh-grey" floating>Date of Birth</ion-label>
                <ion-input type="text" formControlName="dob"></ion-input>
            </ion-item>
            <ion-item>
                <ion-label color="ligh-grey" floating>Phone Number</ion-label>
                <ion-input type="number" formControlName="phone" pattern="[0-9]*"></ion-input>
            </ion-item>
            <ion-item>
                <ion-label color="ligh-grey" floating>Address</ion-label>
                <ion-input type="text" formControlName="address"></ion-input>
            </ion-item>
            <ion-item class="job_status">
                <ion-label color="ligh-grey" floating>Job Status (Position)</ion-label>
                <ion-input type="text" formControlName="jobStatus"></ion-input>
            </ion-item>
            <ion-item>
                <ion-label>Job Sector</ion-label>
                <ion-select formControlName="jobSectore">
                    <ion-option value="f">Government</ion-option>
                    <ion-option value="m">Private</ion-option>
                </ion-select>
            </ion-item>
            <input type="checkbox" formControlName="isTosRead"> -->
      <!-- We can check if our form is valid: -->
      <ion-buttons padding-top>
        <button ion-button full round type="submit" [disabled]="!registrationForm.valid">SIGNUP</button>
      </ion-buttons>
    </form>
    <pre> {{registrationForm.status}}</pre>
    <pre> {{registrationForm.value | json }}</pre>
  </ion-list>
</ion-content>

And this is my TS file

import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams } from 'ionic-angular';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';

@IonicPage()
@Component({
  selector: 'page-registration',
  templateUrl: 'registration.html',
})
export class RegistrationPage {

  registrationForm: FormGroup;
  userName: string;

  constructor(public navCtrl: NavController, public navParams: NavParams, private fb: FormBuilder) {
    // this.registrationForm = new FormGroup({
    //   userName: new FormControl('', [Validators.required, Validators.minLength(2), Validators.pattern('^[a-zA-Z]+$')]),
    //   email: new FormControl('', [Validators.required, Validators.email, Validators.minLength(4)]),
    //   dob: new FormControl('', [Validators.required, Validators.minLength(4)]),
    //   phone: new FormControl('', [Validators.required, Validators.minLength(9), Validators.maxLength(10)]),
    //   address: new FormControl('', [Validators.required, Validators.minLength(9), Validators.maxLength(255)]),
    //   jobStatus: new FormControl('', [Validators.required, Validators.minLength(2), Validators.maxLength(50)]),
    //   jobSectore: new FormControl('', [Validators.required]),
    //   isTosRead: new FormControl(false, [Validators.requiredTrue])
    // })

    this.registrationForm = this.fb.group({
      'userName': [null, Validators.compose([Validators.pattern('^[a-zA-Z]+$'), Validators.required])]
    });
  }
}

What exactly is the wrong here? Why am I not getting the *ngIf condition, console doesn't show me any error.

SiddAjmera
  • 38,129
  • 5
  • 72
  • 110
Sahan Pasindu Nirmal
  • 433
  • 4
  • 13
  • 36

3 Answers3

3

Try changing the condition as follows,

this.registrationForm = this.fb.group({
      userName: [
        null, Validators.compose([Validators.maxLength(30), Validators.pattern('^[a-zA-Z]+$'), Validators.required])
      ],

EDIT

Also change your template as follows,

<ion-item *ngIf="!registrationForm .controls.userName.valid && (registrationForm .controls.userName.dirty)"> <p>Please enter a valid name.</p> </ion-item> 
Sajeetharan
  • 216,225
  • 63
  • 350
  • 396
1

Add <span> tag with your formControl like this :

OR Add class="text-danger" in your current <div>.

.html file.

Display required Error Message

<span class="text-danger" *ngIf="registrationForm.controls['userName'].hasError('required') && (registrationForm.controls['userName'].dirty || registrationForm.controls['userName'].touched)">Field is required</span>

Display pattern Error Message

<span class="text-danger" *ngIf="registrationForm.controls['userName'].hasError('pattern') && (registrationForm.controls['userName'].dirty || registrationForm.controls['userName'].touched)">Enter valid username.</span>

ts file.

this.registrationForm = this.fb.group({
  'userName': [null, Validators.compose([Validators.pattern('^[a-zA-Z]+$'), Validators.required])]
});
Shashikant Devani
  • 2,298
  • 1
  • 12
  • 25
  • Thank you for your effort and kind consideration sir, but it result is same – Sahan Pasindu Nirmal Sep 16 '18 at 13:43
  • Use `p` tag instead of `span` tag. – Shashikant Devani Sep 16 '18 at 13:45
  • no brother here is problem i have not set control object name like this => "!registrationForm.controls.userName.valid" now it is working – Sahan Pasindu Nirmal Sep 16 '18 at 13:49
  • 1
    Okk that's great. – Shashikant Devani Sep 16 '18 at 13:51
  • 1
    `!registrationForm.controls.userName.valid` is really works. But if you want to display different different error message than try my given answer. Ex. In your case. You have two validation for same Control. Like `pattern` and `required`. You can use like `hasError('pattern')` and `hasError('required')`. – Shashikant Devani Sep 16 '18 at 14:03
  • could you give me some example what you taking about sir? :) – Sahan Pasindu Nirmal Sep 16 '18 at 14:08
  • What you do if you want to display different different message for 'pattern' and 'required'? – Shashikant Devani Sep 16 '18 at 14:11
  • pattern error, here i used pattern Validators.pattern('^[a-zA-Z]+$') i have no idea about hasError method and hasError('pattern') sir – Sahan Pasindu Nirmal Sep 16 '18 at 14:12
  • okay and hasError('pattern') method will trigger when user not followed pattern which we set in our ts file? i mean i mention this patter Validators.pattern('^[a-zA-Z]+$') and when your not follow this pattern i can check that using hasError('pattern') this method right? :) – Sahan Pasindu Nirmal Sep 16 '18 at 14:19
  • And your in-build logic here is pretty cool, because it give error when touched, and required and pattern miss match situations. and you set nice error like "enter a valid name" pretty smart. i have break it into 2 just check pattern in another div, but you know what i think your logic is fine and meaning full for every situations – Sahan Pasindu Nirmal Sep 16 '18 at 16:54
1

You'll have to add the error message div outside the ion-item tag like this:

<ion-header>
  <ion-navbar>
    <ion-title>Home</ion-title>
  </ion-navbar>
</ion-header>

<ion-content padding>
  <ion-list class="items-middle" text-center>
    <form [formGroup]="registrationForm">
      <ion-item>
        <ion-label floating>Full Name</ion-label>
        <ion-input type="text" formControlName="userName"></ion-input>
      </ion-item>
      <div *ngIf="registrationForm.get('userName').touched && registrationForm.get('userName').invalid"> name is required</div>
      <ion-buttons padding-top>
        <button ion-button full round type="submit" [disabled]="!registrationForm.valid">SIGNUP</button>
      </ion-buttons>
    </form>
    <pre> {{registrationForm.status}}</pre>
    <pre> {{registrationForm.value | json }}</pre>
    <pre> {{registrationForm.get('userName').invalid | json }}</pre>
    <pre> {{registrationForm.get('userName').touched | json }}</pre>
  </ion-list>
</ion-content>

Also, you can simply use registrationForm.get('userName').touched && registrationForm.get('userName').invalid">

Here's a Sample StackBlitz.

SiddAjmera
  • 38,129
  • 5
  • 72
  • 110