I have the following classes:
class License {
name:string;
.. lots of other fields.
nameAttributes:NameAttributes[];
}
class nameAttributes:NameAttributes{
index:number;
attribute:string;
}
I know I can created the form like this, but it requires that I manually create each field(control) and every time the licences class changes, I have to update the class and this formGroup with the new fields.
this.licenseForm = formBuilder.group({
name:['name value'],
otherFields:['their values'],
nameAttributes: this.formBuilder.array([
this.formBuilder.group({
index:[1],
attribute:["attr1"]
}),
this.formBuilder.group({
index:[2],
attribute:["attr2"]
})
])
});
I would prefer if I could just pass the license class into formBuilder and it would create the necessary FormGroups automatically and make them available based on their name, so the following would create two groups, a "license" group and a nested "nameAttributes" group with all of the associated controls for license and nameAttributes.
this.licenseForm = formBuilder.group({
license:formBuilder.group(license)
});
Am I missing something or is this just not possible without some serious class introspection code?
If your object has data, of course you can do it
Take a look to this stackblitz
You has a function like
createForm(data:any):FormGroup
{
const group=new FormGroup({});
for (let key in data)
{
if (Array.isArray(data[key])) //if is an array
{ //first create the formArray
group.addControl(key,new FormArray([this.createForm(data[key][0])]))
for (let i=1;i<data[key].length;i++) //after add the rest of the elements
(group.get(key) as FormArray).push(this.createForm(data[key][i]))
}
else
{
if (typeof(data[key])=="object") //if is an object we add a formGroup
group.addControl(key,this.createForm(data[key]))
else //add a simple control
group.addControl(key,new FormControl(data[key]))
}
}
return group
}
And call it as
this.form=this.createForm(this.obj)