FormBuilder group is deprecated
Solution 1:
Problem description
From the documentation we see two different lines with the group()
function
group(controlsConfig: { [key: string]: any; }, options?: AbstractControlOptions): FormGroup
AND
group(controlsConfig: { [key: string]: any; }, options: { [key: string]: any; }): FormGroup
The 2nd definition is what is deprecated
The difference in this lines is options?: AbstractControlOptions
and options: { [key: string]: any; }
To understand why angular is throwing this error we will now consider AbstractControlOptions
interface AbstractControlOptions {
validators?: ValidatorFn | ValidatorFn[] | null
asyncValidators?: AsyncValidatorFn | AsyncValidatorFn[] | null
updateOn?: 'change' | 'blur' | 'submit'
}
We continue to breakdown the problem by noting that the difference between this structure and your structure is ValidatorFn[]
interface ValidatorFn {
(control: AbstractControl): ValidationErrors | null
}
Overally, the error is thrown in your case because your Validator
function is expected to take a control and return ValidationErrors | null
. In the line validate(control: AbstractControl): void
, your code actually returns void
but expected to return a ValidationError | null
Solution
From the problem description, the solution is to simply modify the ValidatorFn
Ensure that your ValidatorFn
returns a ValidationError
or if no error returns null
From ValidationErrors defination
type ValidationErrors = {
[key: string]: any;
};
You will need to return a key value pair object e.g {required_if: true}
We can change your code by adding return statements as expected
class ValidateThirdNumber {
static validate(control: AbstractControl): ValidationErrors | null {
if (control) {
const isMultiFlavor = control.get('isMultiFlavor')?.value;
const ingredientFlavor = control.get('ingredientFlavor')?.value;
const ingredientBrand = control.get('ingredientBrand')?.value;
const ingredientName = control.get('ingredientName')?.value;
if (isMultiFlavor && ingredientFlavor.trim().length === 0) {
control.get('ingredientFlavor')?.setErrors({required_if: true});
return ({required_if: true});
} else {
control.get('ingredientFlavor')?.setErrors(null);
}
if (!ingredientFlavor && !ingredientBrand && !ingredientName) {
control.get('ingredientName')?.setErrors({required_at_least: true});
control.get('ingredientFlavor')?.setErrors({required_at_least: true});
control.get('ingredientBrand')?.setErrors({required_at_least: true});
return ({required_at_least: true});
} else {
control.get('ingredientName')?.setErrors(null);
control.get('ingredientFlavor')?.setErrors(null);
control.get('ingredientBrand')?.setErrors(null);
}
if (ingredientBrand && ingredientName && ingredientName === ingredientBrand) {
control.get('ingredientName')?.setErrors({not_the_same: true});
control.get('ingredientBrand')?.setErrors({not_the_same: true});
return ({not_the_same: true});
}
}
return null;
}
}
Solution 2:
I also receive same error, I make following changes.
-
make sure that your validator function signature matches like this. (A function that receives a control and synchronously returns a map of validation errors if present, otherwise null.)
- function Your_Function_Name(ObjectName: AbstractControl): ValidationErrors | null { }
-
and you can change code in the form builder like this.
- const formOptions: AbstractControlOptions = { validators: Your_Function_Name };
-
and in the formbuilder object pass above formOptions object like this
- this.formObject = this.formBuilder.group({ fullName: ['', [Validators.required]] }, formOptions);