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
- Host: GitHub
- URL: https://github.com/abarghoud/ngx-reactive-form-class-validator
- Owner: abarghoud
- License: mit
- Created: 2020-11-03T23:10:57.000Z (over 5 years ago)
- Default Branch: main
- Last Pushed: 2025-06-06T21:17:05.000Z (about 1 year ago)
- Last Synced: 2025-09-21T02:25:51.483Z (9 months ago)
- Language: TypeScript
- Size: 1.18 MB
- Stars: 24
- Watchers: 2
- Forks: 5
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- License: LICENSE.txt
Awesome Lists containing this project
- awesome-angular - ngx-reactive-form-class-validator - A lightweight library for dynamically validate Angular reactive forms using [class-validator](https://github.com/typestack/class-validator) library. (Third Party Components / Form Validation)
- fucking-awesome-angular - ngx-reactive-form-class-validator - A lightweight library for dynamically validate Angular reactive forms using <b><code> 11783⭐</code></b> <b><code> 845🍴</code></b> [class-validator](https://github.com/typestack/class-validator)) library. (Third Party Components / Form Validation)
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.
## 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.