A new way to validate Angular Forms

A new way to validate Angular Forms

If you're working on more data-oriented advanced reactive forms, you'll find that not just inputs, but some of the validators and general stuff aren't readily available in the Angular framework. Then design a custom validation and subscribe to FormControl value changes to meet the functional needs of your application. Most of the time this leads to extra noise in your code and you end up doing the same thing over and over.

Lists some of the current challenges in reactive form validation.

? So there is no simple model object that can define properties based on their respective data types and map directly to reactive forms.

? It is not possible to directly map model object values to reactive forms using validation while creating a FormGroup.

? Manually configure validators for each corresponding property (FormControl).

? If you have a specific need to perform different operations based on each FormControl value change, you should subscribe to corresponding FormControl value changes and perform further activities. This is a bit difficult to handle with large forms.

?? Too much code to manage cross-field and conditional validation when a given FormControl has multiple validators.

Use @rxweb/reactive-form-validators for Angular reactive forms to tackle new approaches and overcome current challenges.

Why @rxweb/reactive-form-validators?

Speaking of typescript, the typescript programming language relies heavily on object-oriented programming techniques that provide more opportunities for writing clean code. This is the main reason why we designed this framework to provide reactive forms based on model objects. This will increase the complexity of your application form, and as your application grows at that point, you will have more flexibility, so don't get bogged down in the chore of compiling subscriptions for validators and other values.

Let's create a model object-based reactive form with decorator-based validation. What is decorator-based validation?

Suppose you only want a few validations on the userName field, such as alpha, minLength, and required. These validations can be set in the form of validation decorators on the userName property of the user model. @rxweb/reactive-form-validators add the configured validation decorators when creating the FormControl for the userName property. Here is a code example:

Functional RequirementHere is the registration form mockup, functional needs and validation rules.

export class User 

??? @alpha()

??? @minLength({ value: 5 })

??? @required()

??? userName: string;

}{        
No alt text provided for this image

User registration form model.

1. All fields marked in red are required.

2. field is valid only if the password and confirmation field values are the same.

3. The fullName property is read-only and represents the combined value of firstName and lastName. When the user enters a value in the appropriate FormControl, the updated value of fullName is immediately reflected in the UI.

The package?installation command?is:

npm install @rxweb/reactive-form-validators

Once the package is installed, We register the?'RxReactiveFormsModule'?in?his?root?module, allowing him?to?use?the services of this framework.

The next?code?sample is

import { NgModule } from '@angular/core'

import { BrowserModule } from '@angular/platform-browser';

import { FormsModule,ReactiveFormsModule } from '@angular/forms';

import { AppComponent } from './app.component';

import {? RxReactiveFormsModule } from "@rxweb/reactive-form-validators"

@NgModule({

? imports:????? [ BrowserModule, FormsModule,ReactiveFormsModule,RxReactiveFormsModule ],

? declarations: [AppComponent],

? bootstrap:??? [ AppComponent]

})

export class AppModule { };        

Once the?RxReactiveFormsModule?is registered, Now we creates a User model with?the appropriate?properties shown in the mockup and applies validation decorators?to?the?required?properties?in?the registration?form.

export class User 

??? @required()

??? firstName: string;

?

??? @required()

??? lastName: string;

?

??? @required()

??? userName: string;

?

??? @required()

??? password: string;

}{        

Following?the?code above,?We applied the?necessary?validation?decorators to the appropriate fields?but missed the second and?third scenarios. In

let's see?how the second and?third?scenarios come true.

The?second scenario is?that he?compares the?values of two controls to meet a requirement. We use a comparison decorator that compares?FormControl?values between fields.

ConfirmPassword's?only property and applied validation?decorator:

@compare({fieldName:'password'}

confirmPassword:string;)        

Here,?to achieve the third scenario, We?do?not subscribe?to his?ValueChanges property, and?when?the?value changes to firstName or lastName He sets a?value in the fullName?field. We make some modifications to?the already defined first name and last name?properties. For us, for firstName and lastName he?uses getter/setter typescript?functions. Here?are the changes:

private _firstName: string = ''

??? private _lastName: string = '';

?

??? fullName: string;

?

??? @required()

??? set firstName(value: string) {

??????? this._firstName = value;

??????? this.setFullName();

??? }

?

??? get firstName(): string {

??????? return this._firstName;

??? }

?

??? @required()

??? set lastName(value: string) {

??????? this._lastName = value;

??????? this.setFullName();

??? }

?

??? get lastName(): string{

?????? return this._lastName;

??? }

?

??? setFullName() {

??????? this.fullName = `${this.firstName} ${this.lastName}`;

??? };        

We applied?his getters/setters to?the firstName and lastName?properties?and created a method?for?setFullName?to update?the?full name value.?Now?the?question arises:

Why?did?We?use the?getter/setter?properties? Called with?a value.?Within?the setter function, We set the value?of his?private property?to?the?corresponding?public?property. This?makes your?application?more flexible?as the same model?is used?in multiple components. We?don't?need to write the same code in multiple components?or?subscribe to ValueChanges. See the?illustration below

No alt text provided for this image

The setter function will call when the firstName FormControl value change.

Now let’s see, the complete User model

import { required,compare } from "@rxweb/reactive-form-validators"

export class User {

??? private _firstName: string = '';

??? private _lastName: string = '';

??? fullName: string;

??? @required()

??? set firstName(value: string) {

??????? this._firstName = value;

??????? this.setFullName();

??? }

??? get firstName(): string {

??????? return this._firstName;

??? }

??? @required()

??? set lastName(value: string) {

??????? this._lastName = value;

??????? this.setFullName();

??? };        

Now, We create a FormGroup from the User model object in the component. We use the ‘form group’ method of RxFormBuilder for creating a FormGroup.

Here is the code :

import { Component, OnInit } from '@angular/core'

import { FormGroup } from "@angular/forms"

import { RxFormBuilder } from '@rxweb/reactive-form-validators';

import { User } from '../user.model';

?

@Component({

??? selector: 'app-user-add',

??? templateUrl: './user-add.component.html'

})

export class UserAddComponent implements OnInit {

?

??? userFormGroup: FormGroup

??? user:User;

??? constructor(

??????? private formBuilder: RxFormBuilder

??? ) { }

?

??? ngOnInit() {

??????? this.user = new User();

??????? this.userFormGroup = this.formBuilder.formGroup(this.user);

??? }

};        

Now, We write the HTML as per angular reactive form standards. But the fullName property is not a FormControl. We used the user object for showing the full name value. See the below code:

<div class="form-group"

??? <label>Full Name : {{user.fullName}}</label>

? </div>>        

要查看或添加评论,请登录

Sandip Poojara的更多文章

  • Razor Pages in ASP.NET Core

    Razor Pages in ASP.NET Core

    In this blog, we are going to discuss Razor pages with Asp.net Core.

    1 条评论
  • Best Practices when using Angular CLI

    Best Practices when using Angular CLI

    Angular is one of the best platforms to create Single Page Applications (SPA). We will go through several practices…

    1 条评论
  • Angular Syncfusion grid

    Angular Syncfusion grid

    Angular is one of the exceptional frameworks of JavaScript. We can use Essential JS 2 grid with angular, which is…

  • MEAN Stack CRUD- Angular 13

    MEAN Stack CRUD- Angular 13

    In this blog, we will look into how to perform Angular 13 crud operation using MEAN stack technology. We will use…

  • Virtual Scrolling- Angular

    Virtual Scrolling- Angular

    Sometimes we as a developer have to show thousands of elements in a single table. When we add these items to one DOM…

  • Debugging Node.js with Google Chrome

    Debugging Node.js with Google Chrome

    In software development, debugging is used when a developer locates a code error in a particular program and is able to…

  • Interaction of NodeJS Services with JSON content using AJAX

    Interaction of NodeJS Services with JSON content using AJAX

    Node.js is an "open-source server-side runtime platform.

  • Lazy Loading Modules in Angular 8

    Lazy Loading Modules in Angular 8

    Lazy loading is a very helpful concept in Angular. It loads NgModuls only when we navigate to rout.

    1 条评论

社区洞察

其他会员也浏览了