Reputation: 99
I am using FormBuilder to build a form :
this.myForm = this.fb.group({
'name': new FormControl(null, Validators.min(5)),
'description': new FormControl(null, Validators.min(60))
});
The problem is I should also validate if it is required and I get it from configuration through a map built like this:
map = new Map<string, boolean>();
map.set('name', true);
map.set('description', false);
The problem can be solved as follows:
this.myForm = this.fb.group({
'name': this.map.get('name') ? new FormControl(null, Validators.compose([Validators.required, Validators.min(5)])) : new FormControl(null, Validators.min(5)),
'description': this.map.get('description') ? new FormControl(null, Validators.compose([Validators.required, Validators.min(60)])) : new FormControl(null, Validators.min(60))
});
That works but imagine in a large application with several forms with lots of fields really is uncomfortable this way of doing it. Ideally it would look something like this:
Object.keys(this.myForm.controls).forEach(key => {
if (map.get(key)) {
this.myForm.get(key).setValidators(this.myForm.get(key).getValidators().push(Validators.required))
}
});
Of course that way does not work. So if someone who has already solved this or has a good way to do what is described above I will thank you very much. Thanks in advance!!!
Update: The problem can be reduced to "how to get all validators associated with a FormControl". I do not think there is a definitive solution to this question --> https://github.com/angular/angular/issues/13461
Upvotes: 2
Views: 1728
Reputation: 8125
Just cleaned/refactor up above code. Create a composer function Please take look
// composer function
const composer = (control: FormControl, ...validators) => {
control.setValidators(Validators.compose([...validators]));
}
for (let name of Object.keys(grp)) {
let control = this.heroForm.controls[name];
if (map.has(name)) {
let validators = control.validator(control);
if (validators && !validators.required) {
let exisitingValidators = control.validators;
composer(control, ...exisitingValidators, Validators.required);
}
}
}
Upvotes: 0
Reputation: 3297
here is a simple solution, i explained it in comments :
Object.keys(this.myForm.controls).forEach(key => {
// if it needs to be required
if (map.get(key)) {
// you have first to check if it already contains validator.required.
let validators = this.myForm.controls[key].validator(this.myForm.controls[key]);
// if it contains it -> {required: true};
// if it doesn't contains it you can now add the required validator
if(validators && !validators.required){
let exisitingValidators = this.myForm.controls[key].validators;
this.myForm.controls[key].setValidators(Validators.compose([...existingValidators ,Validators.required]));
// call updateValueAndValidity to apply the new validators on the control
this.myForm.controls[key].updateValueAndValidity();
}
});
Hope it helps :)
Upvotes: 2