Creating a Custom Validator in Angular 2 with Parameters

The validator function requires two arguments: one for the number of digits before the decimal point and the other for the number of digits after the decimal point. To maintain this, you must provide a fat arrow function. Further information on fat arrow functions can be found at https://basarat.gitbooks.io/typescript/content/docs/arrow-functions.html.

Question:

I have this
custom validator
:

export const mealTypesValidator = (mealSelected: boolean) => {
    return (control: FormControl) => {
        var mealTypes = control.value;
        if (mealTypes) {
            if (mealTypes.length < 1 && mealSelected) {
                return {
                    mealTypesValid: { valid: false }
                };
            }
        }
        return null;
    };
};

If I use it like this it works:

ngOnInit() {
    this.findForm = this.formBuilder.group({
        categories: [null, Validators.required],
        mealTypes: [[], mealTypesValidator(true)],
        distanceNumber: null,
        distanceUnit: 'kilometers',
        keywords: null,
    });
}

The caveat is that the mealSelected property in my component is subject to change whenever the user selects or deselects a meal.

The validator mentioned is called using a static true value that remains constant.

What is the way to make the validator functional while utilizing the parameter of component.mealSelected value?

ngOnInit() {
    this.findForm = this.formBuilder.group({
        categories: [null, Validators.required],
        mealTypes: [[], mealTypesValidator(this.mealSelected)],
        distanceNumber: null,
        distanceUnit: 'kilometers',
        keywords: null,
    });
}

By following the above method,

this.mealSelected

is evaluated immediately which is incorrect. Therefore, when the user chooses a meal, the custom validator does not receive the correct value of true.


Solution:

To resolve the issue, I relocated the validator to my component and utilized

this.mealSelected

for validation. However, I encountered a problem where the validator was not activated when a meal was chosen or unselected, so I employed

this.findForm.controls['mealTypes'].updateValueAndValidity();

to activate the validation process.

The code may be optimized to eliminate the need for the parameter in the custom validator.

ngOnInit() {
    this.findForm = this.formBuilder.group({
        categories: [null, Validators.required],
        mealTypes: [[], this.mealTypesValidator(true)],
        distanceNumber: null,
        distanceUnit: 'kilometers',
        keywords: null,
    });
}
mealTypesValidator = (mealSelected: boolean) => {
    return (control: FormControl) => {
        var mealTypes = control.value;
        if (mealTypes) {
            if (mealTypes.length < 1 && this.mealSelected) {
                return {
                    mealTypesValid: { valid: false }
                };
            }
        }
        return null;
    };
};

Despite this, it would be beneficial to have a validation module that can be centralized for ease of use. If someone knows how to use a dynamic parameter value, such as a component field, as a
parameter to a custom
validator – as I originally requested – I would be grateful for an answer that utilizes this technique.

Frequently Asked Questions