Angular 7 Advance form validation

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

Before get start you must have the knowledge about the validation if you don’t know, Please read the ‘Angular 7 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 method you can define your own error messages. You may notice we have a static method called password. This is our rule for the validation.

Now we will create a new component. Type the below command to create 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 ErrorMessage component 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 ={ firstName: ['', Validators.required], lastName: ['', Validators.required], email: ['', [Validators.required,]], 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 ={ firstName: ['', Validators.required], lastName: ['', Validators.required], email: ['', [Validators.required,]], 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">
<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 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 class="form-group">
<input type="text" formControlName="email" class="form-control" [ngClass]="{ 'is-invalid': submitted &amp;&amp; }" />
<error-message [control]="" *ngIf="submitted"></error-message>
<div class="form-group">
<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 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>

Angular 7 form validation form will looks like this

Related Posts