my API response is like
"groups": [{
"group_name": "GRP1"
"attributes": [{
"attribute_id": 1,
"attribute_name": "Frequency",
"value_reference": "tag"
}]
},
{
"group_name": "GRP2"
"attributes": [{
"attribute_id": 2,
"attribute_name": "Date",
"value_reference": "static",
"value_static_type": "date"
}]
}]
-- How I can create formConrol in Angular 4 to display data like
GroupName
List of Group's Attribute
GroupName
List of Group's Attribute
My initial form control is like
this.editTemplateForm = this.fb.group({
groups: this.fb.group({
group_name: ['', Validators.required ],
attributes : this.fb.group({
value_reference : []
})
}),
});
I don't understand how add control dynamically
The structure here ends up being fairly complicated, if you'd like to match your API response exactly. Since, so far, each attributes property only has a single object of attributes, you could potentially make attributes an Object directly, instead of an array of objects, which would simplify the following code. The code below matches your current API structure, and can be played with at this working plunker.
Some things to keep in mind:
FormGroup needs to be the outer-most form object, and can also be used to hold an indeterminate number of FormControl itemsFormArray, on the other hand, is useful when the number of controls is indeterminate, and it does not matter what those controls are called. allGroups is an array holding the largest groups, and attributes is an array holding your attribute objects, but those attribute objects themselves are groups - because we want to be able to name the controls based on their API property nameThere's also a good chance this structure isn't exactly what you're looking for (e.g. perhaps you didn't want all these values to be editable <input> fields), but it should give you a strong basis to play with on the plunker, and understand how you can dynamically generate HTML based on changing form objects.
import {Component} from '@angular/core';
import {FormGroup, FormControl, FormArray, FormBuilder} from '@angular/forms';
interface APIGroup {
'group_name': string;
'attributes': Array<GroupAttributes>
}
interface GroupAttributes {
'attribute_id': number;
'attribute_name': string;
'value_reference': string;
'value_static_type'?: string;
}
@Component({
selector: 'app-child',
template: `
<div>
<h3>I'm the Child component</h3>
</div>
<form [formGroup]="editTemplateForm">
<div formArrayName="allGroups">
<div *ngFor="let group of editTemplateForm.get('allGroups').controls; let i=index" [formGroupName]="i">
<input formControlName="groupName" />
<div formArrayName="attributes">
<div *ngFor="let attributeGroup of group.get('attributes').controls; let n=index" [formGroupName]="n">
<input *ngFor="let key of keysOfFormGroup(attributeGroup)" [formControlName]="key" />
</div>
</div>
<br/>
</div>
</div>
</form>
<pre style="background: #ddd">{{editTemplateForm.value | json}}</pre>
`,
})
export class ChildComponent {
constructor(
private fb: FormBuilder
) { }
sampleData: Array<APIGroup> = [
{
"group_name": "GRP1",
"attributes": [{
"attribute_id": 1,
"attribute_name": "Frequency",
"value_reference": "tag"
}]
},
{
"group_name": "GRP2",
"attributes": [{
"attribute_id": 2,
"attribute_name": "Date",
"value_reference": "static",
"value_static_type": "date"
}]
}
]
editTemplateForm: FormGroup;
ngOnInit() {
this.editTemplateForm = this.fb.group({
allGroups: this.fb.array([])
});
// would call on a subscription to actual api data
this.sampleData.forEach(group => {
(<FormArray>this.editTemplateForm.get('allGroups'))
.push(this.initGroup(group));
});
}
initGroup(apiGroup: APIGroup): FormGroup {
let formGroup = this.fb.group({
groupName: [apiGroup.group_name],
attributes: this.fb.array([])
});
apiGroup.attributes.forEach(attributeGroup => {
(<FormArray>formGroup.get('attributes'))
.push(this.initAttributeGroup(attributeGroup));
});
return formGroup;
}
initAttributeGroup(attributes: GroupAttributes): FormGroup {
let formGroup = this.fb.group({});
Object.keys(attributes).forEach(name => {
formGroup.addControl(name, new FormControl(attributes[name]));
});
return formGroup;
}
keysOfFormGroup(group: FormGroup): Array<string> {
return Object.keys(group.controls);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With