Angular 8 Advance Form Validation Tutorial Example

Overview

In this Angular 8 form validation tutorial, we will show you how to create a public message for the form validation and custom validation rules. This will make easy to use and flexible.

Before getting started you must have the knowledge about the validation if you don’t know, please read the ‘Angular 8 Form Validation‘ post first.

Let’s get started

First, we will create a service. In this service, we will define our error messages and custom validation method.

Type the below command to create a service

 ng g service validation

Replace the file with the below code

import { Injectable } from '@angular/core';
import { FormControl, FormGroup } from '@angular/forms';
 
@Injectable({
  providedIn: 'root'
})
export class ValidationService {
 
  constructor() { }
 
  static getValidatorErrorMessage(validatorName: string, validatorValue?: any) {
 
    let config = {
        'required': 'This field is required',
        'email': 'The ' + validatorName + ' must contain a valid email address',
        'invalidPassword': 'Password must be at least 6 characters long, and contain a number.',
        'minLength': `Minimum length ${validatorValue.requiredLength}`,
        'invalidMatch': 'The password and confirm password must match'
 
    };
 
    return config[validatorName];
  }
   
  static password(control: FormControl) {
     
    // {6,100}           - Assert password is between 6 and 100 characters
    // (?=.*[0-9])       - Assert a string has at least one number
    if (control.value.match(/^(?=.*[0-9])[[email protected]#$%^&*]{6,100}$/)) {
        return null;
    } else {
        return { 'invalidPassword': true };
    }
  }
 
  static match(controlName: string, matchingControlName: string) {
 
    return (formGroup: FormGroup) => {
      const control = formGroup.controls[controlName];
      const matchingControl = formGroup.controls[matchingControlName];
 
      if (matchingControl.errors && !matchingControl.errors.invalidMatch) {
          return;
      }
 
      // set error on matchingControl if validation fails
      if (control.value !== matchingControl.value) {
          matchingControl.setErrors({ invalidMatch: true });
      } else {
          matchingControl.setErrors(null);
      }
  }
  }
}

Here under the getValidatorErrorMessage the method you can define your own error messages. You may notice we have a static method called password. This is our rule for validation.

Now we will create a new component. Type the below command to create a component

ng g component errorMessage

Open the error-message.component.ts file and put the below code on it

import { Component, OnInit, Input } from '@angular/core';
import { FormControl } from '@angular/forms';
import { ValidationService } from '../validation.service';
 
@Component({
  selector: 'error-message',
  templateUrl: './error-message.component.html',
  styleUrls: ['./error-message.component.css']
})
export class ErrorMessageComponent {
  @Input() control: FormControl;
 
  constructor() { }
   
  get errorMessage() {
    for (let propertyName in this.control.errors) {
      if (this.control.errors.hasOwnProperty(propertyName)) {
        return ValidationService.getValidatorErrorMessage(propertyName, this.control.errors[propertyName]);
      }
    }    
    return null;
  }
}

Then open the error.message.component.html file and put the below html

 <div class="text-danger" *ngIf="errorMessage !== null">{{errorMessage}}</div> 

Now register ValidationService service and ErrorMessagecomponent for our application. So that we can use in our application. To registered open app.module.ts file and import the ValidationService service and ErrorMessage component.

 import { ValidationService } from './validation.service';
import { ErrorMessageComponent } from './error-message/error-message.component';

Then add the ValidationService in the providers like the below.

providers: [ ValidationService ]

Then add the ErrorMessageComponent in the declarations

declarations: [
 ..
 ErrorMessageComponent
 ] 

After adding the validationService our app.module.ts file will looks like this

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
 
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { HttpClientModule } from '@angular/common/http';
import { FormComponent } from './form/form.component';
import { RegisterComponent } from './register/register.component';
import { ErrorMessageComponent } from './error-message/error-message.component';
import { ValidationService } from './validation.service';
 
 
@NgModule({
  declarations: [
    AppComponent,
    FormComponent,
    RegisterComponent,
    ErrorMessageComponent,
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    FormsModule,
    HttpClientModule,
    ReactiveFormsModule,
  ],
  providers: [ ValidationService ],
  bootstrap: [AppComponent]
})
export class AppModule { }

Now our error-message component and new validation rules is ready to use.

Open your app.component.ts file and import the ValidationService

import { ValidationService } from './validation.service';

Then add the rules in the form group

this.registerForm = this.formBuilder.group({
  firstName: ['', Validators.required],
  lastName: ['', Validators.required],
  email: ['', [Validators.required, Validators.email]],
  password: ['', [Validators.required, Validators.minLength(6)]],
  confirmPassword: ['', [Validators.required, ValidationService.password]]
},{
  validator: [
    ValidationService.match('password', 'confirmPassword'),
  ]
});

After the changes our app.component.ts file will looks like this

import { Component } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { ValidationService } from './validation.service';
 
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'helloworld';
  registerForm: FormGroup;
  submitted = false;
 
  constructor(private formBuilder: FormBuilder) { }
 
  ngOnInit() {
    this.registerForm = this.formBuilder.group({
      firstName: ['', Validators.required],
      lastName: ['', Validators.required],
      email: ['', [Validators.required, Validators.email]],
      password: ['', [Validators.required, Validators.minLength(6)]],
      confirmPassword: ['', [Validators.required, ValidationService.password ]]
    }, {
      validator: [
        ValidationService.match('password', 'confirmPassword'),
      ]
    });
   
  }
 
  onSubmit() {
    this.submitted = true;
 
    // stop the process here if form is invalid
    if (this.registerForm.invalid) {
        return;
    }
 
    alert('SUCCESS!!');
}
 
}

Then open the app.component.html file and replace the html with the below html

<div class="container">
    <div class="row">
        <div class="col-md-6 offset-md-3">
            <h3>Register</h3>
            <form [formGroup]="registerForm" (ngSubmit)="onSubmit()">
                <div class="form-group">
                    <label>First Name</label>
                    <input type="text" formControlName="firstName" class="form-control" [ngClass]="{ 'is-invalid': submitted &amp;&amp; registerForm.controls.firstName.errors }" />
                    <error-message [control]="registerForm.controls.firstName" *ngIf="submitted"></error-message>
                </div>
                <div class="form-group">
                    <label>Last Name</label>
                    <input type="text" formControlName="lastName" class="form-control" [ngClass]="{ 'is-invalid': submitted &amp;&amp; registerForm.controls.lastName.errors }" />
                    <error-message [control]="registerForm.controls.lastName" *ngIf="submitted"></error-message>
                </div>
                <div class="form-group">
                    <label>Email</label>
                    <input type="text" formControlName="email" class="form-control" [ngClass]="{ 'is-invalid': submitted &amp;&amp; registerForm.controls.email.errors }" />
                    <error-message [control]="registerForm.controls.email" *ngIf="submitted"></error-message>
                </div>
                <div class="form-group">
                    <label>Password</label>
                    <input type="password" formControlName="password" class="form-control" [ngClass]="{ 'is-invalid': submitted &amp;&amp; registerForm.controls.password.errors }"  />
                    <error-message [control]="registerForm.controls.password" *ngIf="submitted"></error-message>
                </div>
                <div class="form-group">
                    <label>Confirm Password</label>
                    <input type="password" formControlName="confirmPassword" class="form-control" [ngClass]="{ 'is-invalid': submitted &amp;&amp; registerForm.controls.confirmPassword.errors }"  />
                    <error-message [control]="registerForm.controls.confirmPassword" *ngIf="submitted"></error-message>                    
                </div>
                <div class="form-group">
                    <button class="btn btn-primary">Register</button>
                </div>
            </form>
        </div>
    </div>
</div>

Angular8 form validation form will looks like this

This article is originally published at https://w3path.com

Be First to Comment

Leave a Reply

Your email address will not be published. Required fields are marked *