I have a custom component inheriting ControlValueAccessor on my application that integrate ng-select
The goal of this component is to have one central place where ng-select is integrated so I can re-use it across the application.
This is how I call the validation method:
constructor(
@Optional() @Self() public controlDir: NgControl
) {
controlDir.valueAccessor = this;
}
ngOnInit() {
const control = this.controlDir.control;
if (control.validator) {
control.setValidators([this.validate.bind(this, [control.validator])]);
}
control.updateValueAndValidity({ emitEvent: false });
}
validate(validators: ValidatorFn[], c: FormControl) {
const allErrors: any = {};
for (const validator of validators) {
const hasError = validator(c);
if (hasError) {
Object.entries(hasError).forEach(([errorName, isOnError]) => {
allErrors[errorName] = isOnError;
});
}
}
if (Object.keys(allErrors).length > 0) {
return allErrors;
}
return null;
}
And this is how I would typically instantiate the formControl on the parent component:
const control = this.formBuilder.control(['[email protected]'], [Validators.email]);
this.form = this.formBuilder.group({ test: control });
I want to give the parent the option to use Built-in angular validators on my custom component. (required, email, min, max...).
The problem is that the control value of my custom component is an array of string, for instance the value will be:
[ '[email protected]', '[email protected]' ]
the component looks like this
Problem: in my validate function, I have access to a ValidatorFn that will check if my control is a valid email. if my control value was a string, it would work as expected but it's an array of string, so it's not working.
So my guess is that i need to re-implement the email validator for my custom component (as it makes sense that angular can't figure out magically the structure of my data within my custom component).
But I can't figure out how to identify that the validator defined is Validator.email
.
this.controlDir.control.validator
is a function and I have no clue how to identify that it's the email validator so I can add my custom validation for emails.
Question: How can I know from my custom validate function which Validator was set from the parent? Was it Validators.required, Validators.email ...etc
Unfortunately there is no way to get the validators for a given control (details).
In theory, you could iterate over your control value (if it is an array) and create a new
FormControl
to validate each string in the array.As an example you could do it like this:
Use it like this perhaps
You can implement it however you want, but the idea is simply to validate each string using it's own form control.
There might be some obscure way to achieve this differently using
NG_VALIDATORS
but I have not looked into it.