Reputation: 754
I am creating Dynamic Reactive form in Angular. But in the below code level.name is not being accepted as compiler is not allowing to give variable inside the group(). It is only allowing fixed value like - state, city etc instead of level.name variable where level is an object which has name field...
this.countryNextLevelsBeforeMan.forEach(**level** => {
let l2 =<FormArray> this.l1FormGroup2.controls["l2"];
l2.push(this.formBuilder.group({
**level.name** : null --> compilation error on this line as variable not getting allowed
}))
});
Inside the group method I want to give control name as a variable (level.name). In the for loop if level is {"name" : "State" , "id" : 2} then I want to set it like below,
l2.push(this.formBuilder.group({
**State** : null --> No compilation error if we give fixed value
}))
(Instead of 'State' I want it to be dynamically assigned by level.name as level.name can be City, Street etc)
Please help!!!
Upvotes: 2
Views: 5204
Reputation: 15947
Most of the posts here require FormBuilder and other dependencies. But you can add "named" FormControl Reactive Angular controls to an associative array with string names dynamically, then bolt that onto a FormGroup as follows:
First, create a custom Form Control list as an associative array with string key names (typed for TypeScript type compliance) as so:
let formControlsList: {[key: string]: FormControl} = {};
Second, add each FormControl
object you define to your dynamic FromControl list using string variable names (Note below your Validators
can be an array of validators):
let fields: string[] = ["id", "name", "city"];
// Loop through the string array and use them to assign your FormControls
// to your array of controls as so...
for (let i = 0; i < fields.length; i++) {
formControlsList[fields[i]] = new FormControl('', Validators.required);
}
Third, simply add your array of named FormControls
stored in the associative array to a FormGroup
:
let myFormGroup = new FormGroup(formControlsList));
Because FormGroup
when created accepts a collection of named form controls as so...
controls : {
[key:string]: FormControl<any>;
}
... your code above will add the following associative array to it that you built above...
{
id: new FormControl(...),
name: new FormControl(...),
city: new FormControl(...)
}
From here you can build dynamic FormGroups
and their child FormControls
under a single parent FormGroup
with FormArray
child.
Enjoy!
Upvotes: 0
Reputation: 58099
SuryaN, if you want to create a FormGroup with "dynamic FormControl name" use the method addControl of a FormGroup. I suggest create a function that return a formGroup from an array of names
getFormGroup(names:string[])
{
const group=new FormGroup({}) //<---create a formGroup empty
names.ForEach(x=>{
group.AddControl(x,new FormControl())
})
return group;
}
So you can call the function like
const group=this.getFormGroup(this.countryNextLevelsBeforeMan.map(x=>x.name))
//make what ever you want with the FormGroup
Upvotes: 1
Reputation: 27471
Try this:
this.countryNextLevelsBeforeMan.forEach(level => {
let l2 =<FormArray> this.l1FormGroup2.controls["l2"];
l2.push(this.formBuilder.group({
[level.name]: null,
[level.id]: []
}))
});
Upvotes: 8