
Parametrized Validators in Dynamic Forms
TL;DR
We are building the documentation of@myndpm/dyn-forms
atmynd.dev and we've added support for a variety of custom functions like Validators, AsyncValidators, Matchers, Conditions and more.
The next crucial part of any form is validation, akaValidators
andAsyncValidators
, and we took some time to study a nice way to implement them and we picked the most declarative one:
createMatConfig('INPUT',{name:'quantity',validators:['required',['min',1]],asyncValidators:['myAsyncValidator'],
Angular Validators
Angular provides defaultValidators that we're used to consume programatically in our Reactive Forms, some of them are Validator Functions (ValidatorFn
) likeValidators.required
, and some others are Validator Factories ((args) => ValidatorFn
) which builds a Validator based on a required parameter likeValidators.minLength(4)
.
The definition of a Validator Function is:
(control:AbstractControl)=>ValidationErrors|null
it receives the control to be validated, and returnsnull
if its value is valid, or an error object of the form{ [error: string]: any }
Validator Factories are high-order functions that builds a Validator Function according some input parameters:
functionminLength(minLength:number):ValidatorFn{return(control:AbstractControl)=>{return(control.value&&control.value.length<minLength)?{minLength:true}// invalid:null;// valid}}
as you can see, this is a very nice way to parametrize our Functions, so we defined the provisioning of Validators (and all the other handlers) with anid
and a factoryfn
:
exportinterfaceDynControlValidator{id:string;fn:(...args:any[])=>ValidatorFn;}
Theid
will be the string that we will use in our Configuration Object. By default,@myndpm/dyn-forms
provide the default Angular Validators with the same name as we know them:required
,requiredTrue
,email
,pattern
,minLength
,maxLength
,min
andmax
.
The notation to use them in the Config Object is as follows:
// without parametersvalidators:['required'],// with parameters as arrayvalidators:['required',['min',1]],// with parameters as objectvalidators:{required:null,minLength:4},// with an inline ValidatorFn or ValidatorFn factoryvalidators:[myValidatorFn,myValidatorFactory(args)],
supporting these different notations is unexpensive and can be useful for different kind of systems or developer tastes.
Custom Validators
As mentioned, all we need is to provide ourValidatorFn
Factory with anid
and afn
. So we can easily provide them in our module with a code like this:
import{AbstractControl,ValidatorFn}from'@angular/forms';import{DynFormsModule}from'@myndpm/dyn-forms';import{DynControlValidator}from'@myndpm/dyn-forms/core';constvalidators:DynControlValidator[]=[{id:'email',fn:():ValidatorFn=>{return(control:AbstractControl)=>{// implement my validator// to return { email: true } | null;}}}];@NgModule({imports:[DynFormsModule.forFeature({validators,priority:100});
note thepriority
parameter to override the default validators (which weight is 0); we will play with priorities in a further article.
AsyncValidators
Providing async validators works in the same way. You provide yourfn
with anid
and use them in the Config Object:
createMatConfig('INPUT',{name:'quantity',validators:['required'],asyncValidators:['myAsyncValidatorId'],
and if you need to provide arguments to your AsyncValidator factory, you can use:
// single argument which can be an objectasyncValidators:[['myAsyncValidatorId',args]],// your factory will receive fn(args)// multiple arguments in array to be destructuredasyncValidators:[['myAsyncValidatorId',[arg1,arg2]]],// your factory will receive fn(arg1, arg2)
Custom Handlers
With this notation we added support for multiple kinds of functions that we require in the Dynamic Forms:Validators
andAsyncValidators
as we just saw,Matchers
andConditions
to manipulate the controls under some special requirements, and alsoParamFns
to inject functions to the parameters of the DynControls too.
We will be digging into the conditional executions in the next chapter.
In the meantime, what do you think of this notation?
// PS. We are hiring!
Top comments(0)
For further actions, you may consider blocking this person and/orreporting abuse