Surya
Surya

Reputation: 754

Can't set variable as FormControl name when creating Dynamic Reactive Form in Angular

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

Answers (4)

Stokely
Stokely

Reputation: 15947

Angular : Create and Add Dynamic Named FormControls to a FormGroup

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));

That's it!

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

Eliseo
Eliseo

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

Chellappan வ
Chellappan வ

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

surendra kumar
surendra kumar

Reputation: 1780

Replace the below line as...

level.name

to

level[name]

Upvotes: 0

Related Questions