An open API service indexing awesome lists of open source software.

https://github.com/abarghoud/ngx-reactive-form-class-validator


https://github.com/abarghoud/ngx-reactive-form-class-validator

Last synced: 4 months ago
JSON representation

Awesome Lists containing this project

README

          

# ngx-reactive-form-class-validator
A lightweight library for dynamically validate Angular reactive forms using [class-validator](https://github.com/typestack/class-validator) library.



npm version
 

npm minified size
 

Code coverage
 

Build status
 

## Table of contents
- [Table of Contents](#table-of-contents)
- [Installation](#installation)
- [Peer dependencies](#peer-dependencies)
- [Usage](#usage)
- [Defining classes with validators](#defining-classes-with-validators)
- [Untyped classes](#untyped-classes)
- [Creating a ClassValidatorFormGroup](#creating-a-classvalidatorformgroup)
- [Using ClassValidatorFormBuilderService](#using-classvalidatorformbuilderservice)
- [Using ClassValidatorFormGroup class](#using-classvalidatorformgroup-class)
- [Eager Validation Option]()
- [Add custom validators](#add-custom-validators)
- [Providing validators when creating the ClassValidatorFormControl](#providing-validators-when-creating-the-classvalidatorformcontrol)
- [Providing validators using `setValidators`/`setValidatorsWithDynamicValidation` methods](#providing-validators-using-setvalidatorssetvalidatorswithdynamicvalidation-methods)
- [Available classes](#available-classes)
- [ClassValidatorFormBuilderModule](#classvalidatorformbuildermodule)
- [ClassValidatorFormBuilderService](#classvalidatorformbuilderservice)
- [classType parameter](#classtype-parameter)
- [ClassValidatorFormGroup](#classvalidatorformgroup)
- [Stackblitz example](https://stackblitz.com/edit/ngx-reactive-form-class-validator-4pbcrp)
- [Developer note](#developer-note)

## Installation

npm install --save ngx-reactive-form-class-validator

// OR

yarn add ngx-reactive-form-class-validator
### Peer dependencies
"@angular/common": ">=2 <22",
"@angular/core": ">=2 <22",
"@angular/forms": ">=2 <22",
"class-validator": ">=0.12 <0.15"

###### _While this library will function with any version of class-validator within this range, we strongly recommend using class-validator ^0.14.0 or later due to a critical [security vulnerability](https://github.com/typestack/class-validator/blob/develop/CHANGELOG.md#:~:text=forbidUnknownValues%20option%20is%20enabled%20by%20default) addressed in versions 0.14.0 and beyond. This ensures the highest level of security for your application._

## Usage
### Defining classes with validators and deserializers
**Please note that properties without a class-validator decorator will not be validated, see [class-validator](https://github.com/typestack/class-validator)**
profile.ts

import { IsEmail, IsNotEmpty, ValidateNested } from 'class-validator';

class Profile {
@IsNotEmpty()
public firstName: string;

@IsNotEmpty()
public lastName: string;

@IsEmail()
public email: string;

@ValidateNested()
public address: Address;
}
address.ts

import { IsNotEmpty, IsOptional, ValidateNested } from 'class-validator';

class Address {
@IsNotEmpty()
public street: string;

@IsNotEmpty()
public city: string;

@IsOptional()
public state: string;

@IsNotEmpty()
public zip: string;
}

### Untyped classes
Untyped version of ngx-class-validator form classes exist in order to be backward compatible with angular untyped form classes
### Creating a ClassValidatorFormGroup
#### Using ClassValidatorFormBuilderService
As described [here](#classvalidatorformbuilderservice) to be able to use the `ClassValidatorFormBuilderService`, you need to import [ClassValidatorFormBuilderModule](#classvalidatorformbuildermodule).

app.module.ts

imports: [
...
ClassValidatorFormBuilderModule.forRoot(),
...
],
Then in your component
profile-form.component.ts

public constructor(
private fb: ClassValidatorFormBuilderService,
) { }

profileForm = this.fb.group(Profile,
{
firstName: [''],
lastName: [''],
email: [''],
address: this.fb.group(Address,
{
street: [''],
city: [''],
state: [''],
zip: ['']
}
),
});
#### Using ClassValidatorFormGroup class
As it's possible with angular `FormGroup` class we can directly create a `ClassValidatorFormGroup` using the constructor

export class ProfileFormComponent {
profileForm = new ClassValidatorFormGroup({
firstName: new ClassValidatorFormControl(''),
lastName: new ClassValidatorFormControl(''),
});
}

Now, setting value to any of form controls, will perfom the validator set in the corresponding class.

this.profileForm.controls.email.setValue('notEmailValue');
console.log(this.profileForm.controls.email) // { isEmail: 'email must be an email' }

this.profileForm.controls.email.setValue('email@email.com');
console.log(this.profileForm.controls.email) // null

#### Eager Validation Option

By default, `ngx-reactive-form-class-validator` validates form controls after the form is fully initialized (ngAfterViewInit).
If you want validation to run immediately after form initialization (for example, in ngAfterViewInit or just after you create a FormGroup), you can enable eager validation at the ClassValidatorFormGroup/FormBuilder level.

```
import { ClassValidatorFormGroup, ClassValidatorFormControl } from 'ngx-reactive-form-class-validator';

const formGroup = new ClassValidatorFormGroup({
email: new ClassValidatorFormControl(''),
password: new ClassValidatorFormControl('')
}, null, { eagerValidation: true }); // 👈 Enable eager validation here

// Or using the form builder

public constructor(
private fb: ClassValidatorFormBuilderService,
) { }

profileForm = this.fb.group(
Profile,
{
firstName: [''],
lastName: [''],
email: [''],
address: this.fb.group(Address,
{
street: [''],
city: [''],
state: [''],
zip: ['']
}
),
},
undefined,
{ eagerValidation: true } // 👈 Enable eager validation here
);

```

### Add custom validators
It is possible as well to combine dynamic validation with custom validation.
There are several ways to do it:
#### Providing validators when creating the ClassValidatorFormControl

this.fb.group (Profile, {
email: ['', Validators.required],
...
}
)

// OR

new ClassValidatorFormGroup(Profile, {
email: new ClassValidatorFormControl('', Validators.required)
})
#### Providing validators using `setValidators`/`setValidatorsWithDynamicValidation` methods
Both `setValidators` and `setValidatorsWithDynamicValidation` replace validators provided in parameter, the only one difference is that `setValidatorsWithDynamicValidation` add given validators as well as re-enable dynamic validation, as the `setValidators` method replace validators with given ones without re-enabling dynamic validation.

emailControl.setValidators(Validators.required); // there will be only Validators.required validator

emailControl.setValidatorsWithDynamicValidation(Validators.required) // there will be Validaros.required validator as well as dynamic validator

## Available classes
### ClassValidatorFormBuilderModule
An Angular module that provides [ClassValidatorFormBuilderService](#classvalidatorformbuilderservice) for dependency injection.
It can either be imported `forRoot` or normally (We don't recommend importing it normally because that will create multiple instances of [ClassValidatorFormBuilderService](#classvalidatorformbuilderservice)).

app.module.ts

imports: [
...
ClassValidatorFormBuilderModule.forRoot(),
...
],
### ClassValidatorFormBuilderService
An Angular injectable service having the same methods as Angular [FormBuilder](https://angular.io/api/forms/FormBuilder) except a minor change of `group` method signature, see below:

group(
classType: ClassType, // The class type of the form group value.
// Angular FormBuilder group method parameters
controlsConfig: { [p: string]: any },
options?: AbstractControlOptions | { [p: string]: any } | null,
): ClassValidatorFormGroup;

#### classType parameter
We've introduced a new parameter called `classType` (a class type containing [class-validator](https://github.com/typestack/class-validator) decorators) that you should provide, to enable us to perform dynamic validations.
### ClassValidatorFormGroup
A typescript class extending angular [FormGroup](https://angular.io/api/forms/FormGroup) class, with a minor change of `constructor` signature, the [classType parameter](#classType-parameter).

export class ClassValidatorFormGroup extends FormGroup {
public constructor(
private readonly classType: ClassType,
// Angular FormGroup constructor parameters
controls: {
[key: string]: AbstractControl;
},
validatorOrOpts?: ValidatorFn | ValidatorFn[] | AbstractControlOptions | null,
asyncValidator?: AsyncValidatorFn | AsyncValidatorFn[] | null,
) {
...
}
### ClassValidatorFormControl
A typescript class extending angular [FormControl](https://angular.io/api/forms/FormControl) class, that will use the [classType](#classtype-parameter) instance to perform validations and assign validation errors to the `ClassValidatorFormControl`.

As it extends angular [FormControl](https://angular.io/api/forms/FormControl) class, it contains all `FormControl` methods, with a custom new method:

setValidatorsWithDynamicValidation(newValidator: ValidatorFn | ValidatorFn[] | AbstractControlOptions | undefined): void

This method has the same signature as FormControl [setValidators](https://angular.io/api/forms/AbstractControl#setValidators) method. In addition it re-enables dynamic validation when disabled.

## Developer note
We are open for proposals, so please don't hesitate to create issues if you want to report any bugs/proposals/feature requests.