It’s easy to work with angular validation either if you use template driven or reactive forms.
in this article we will focus on working with reactive form how to avoid legacy code like this:
<form [formGroup]="formGroup"> <label for="email">Email</label> <input id="email" type="email" formControlName="email"> <span class="error" *ngIf="formGroup.controls['email'].touched && formGroup.controls['email'].errors['required']"> Email is required </span> <span class="error" *ngIf="formGroup.controls['email'].touched && formGroup.controls['email'].errors['email']"> Please provide valid email </span> <button type="submit">submit</button> </form>
in preview example every time need new validation you should add new span item and repeat check condition.
to avoid this and use more clean code we will create a dumb component called “error-field”
ng g c error-field
typescript file will be
import { FormControl, AbstractControl, FormGroupDirective } from '@angular/forms'; import { Component, Input } from '@angular/core'; @Component({ selector: 'error-field', templateUrl: './error-field.component.html', styleUrls: ['./error-field.component.scss'], host: { style: 'color: red;' }, }) export class ErrorFieldComponent { @Input() control: FormControl | AbstractControl @Input() errorMessages: Object constructor(public formDirective:FormGroupDirective){ } }
control and errorMessages it’s just input to provide formControl and all error messages and we will inject formDirective in constructor to catch form submitted.
and but in it’s html
<ng-container *ngIf="control.errors &&(control.touched|| formDirective.submitted)"> {{errorMessages|validation:control.errors}} </ng-container>
first we checked if error exist and control touched or form submitted to prevent show error immediately.
and as you noticed we need validation pipe to take all messages as value and control error as arguments
ng g p validation
pipe simply assign a error message with first control error, we often didn’t need more then one message show in same time.
import { Pipe, PipeTransform } from '@angular/core'; @Pipe({ name: 'validation' }) export class ValidationPipe implements PipeTransform { transform(value: any, errorObj: Object): unknown { return value[Object.keys(errorObj)[0]]; } }
Finally, all you have to use it is provide control and messages.
<form [formGroup]="formGroup"> <label for="email">Email</label> <input id="email" type="email" formControlName="email"> <error-field [control]="formGroup.controls['email']" [errorMessages]="validationMessages.email"> </error-field> <button type="submit">submit</button> </form>
validation message object should be like this
validationMessages = { email: //key is a control name { // and this is a validation key and message required: 'Email is required', email:'Please provide valid email' } }
now every time you need new validation just add it to your form control and add a key : value message to validationMessages object .
Hope you find this usefull.
Relevant Information:
In an era defined by digital transformation, businesses strive to stand out and reach their target audience in unique and engaging ways. One company at the forefront of this innovation is Angrio Technologies, an emerging tech powerhouse that's setting a new standard in the world of technology with its cutting-edge front-end solutions.
At Angrio Technologies, the team understands that a company's website is often the first touchpoint for potential customers. Angular, a powerful front-end framework, empowers Angrio's developers to create robust and responsive web applications that not only load quickly but provide a seamless and engaging user experience.
By creating robust web applications and cross-platform mobile apps, Angrio elevates technology performance and drives engagement to new heights. so visit now
More content at AngrioTechnologies.
Follow us on Twitter, LinkedIn
Follow me on LinkedIn