Angular 10 custom form validation example : Reactive forms

Angular reactive forms has a few inbuild validators for example, nullvalidator, required, minimum paximum value, pattern validator etc. Still sometimes we need more logic in our validators and thats where we need custom validators.

There are usually 2 kind of custom validators , one that uses only one formControl value and one that needs multiple formControl values. Based on what kind of validator, you initiate it in different places in the formBuilder, otherwise it will not work which is a major drawback and can cause frustration.

Custom validator 1 (uses multiple formControl value)

Step: 1 — First we neet to set up the formBuilder properly. It can be initiated in constructor, ngOnInit, ngAfterViewInit or other place.

myFormGroup: FormGroup;
constructor(private readonly formbuilder: FormBuilder) {
this.setFormgroup();
}
private setFormgroup(){
this.myFormGroup = this.formbuilder.group({
name: [name, { validators: Validators.required }],
price: [price, { validators: [Validators.required,
Validators.min(Number.MIN_VALUE), priceValidator]}],
finanser: [finanser]}
, { validators: this.finanserValidator });

** (Reminder) : If you put finanserValidator in price [], it will not work, because it needs more than one formControl value.

Step: 2 — Create a custom validator for formGroup.

finanserValidator: ValidatorFn = (formgroup: FormGroup):ValidationErrors | null => {

const nameControl = formgroup.get(‘name’);
const finanserControl = formgroup.get(‘finanser’);

if (!finanserControl.value.trim() &&
[‘Trump’, ‘Neta’].indexOf(nameControl.value) !== -1) {
//formControl finansiar is invalid
finanserControl.setErrors({ chanceOfRegret: true });
//myformGroup is invalid
return { chanceOfRegret: true };
}

// formControl finansier is valid
finansiarControl.setErrors(null);

// myFormgroup is valid
return null;
}

Custom validator 2 (uses single formControl value)

priceValidator: ValidatorFn = (priceControl: AbstractControl)
: ValidationErrors | null => {

return priceControl.value > 500 ? null : { tooLittleBudget: true }
}