I'm building a form with the structure below:
{
"name": "root_test_name",
"definition": {
"name": "definition_test_name",
"components": [
{
"name": "component_0_name",
"info": {
"name": "info_component_0_name"
}
},
{
"name": "component_1_name",
"info": {
"name": "info_component_1_name"
}
},
{
"name": "component_2_name",
"info": { // <--Error on all attempts to set the formGroup name for this one :(
"name": "info_component_2_name"
}
}
]
}
}
Using the reactive form, I'm able to display controls for all items, except the "name" inside the "info" formGroup. Stackblitz demo here
Here is my AppComponent:
import { Component, VERSION } from '@angular/core';
import { FormArray, FormBuilder, FormGroup, Validators } from '@angular/forms';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent {
name = 'Angular ' + VERSION.major;
constructor(private fb: FormBuilder) {
this.addComponent('component_0_name');
this.addComponent('component_1_name');
this.addComponent('component_2_name');
}
componentForm = this.fb.group({
name: ['root_test_name', Validators.required],
definition: this.fb.group({
name: ['definition_test_name'],
components: this.fb.array([]),
}),
});
components(): FormArray {
return this.componentForm.get('definition').get('components') as FormArray;
}
componentInfo(componentIndex: number): FormGroup {
return this.components().at(componentIndex) as FormGroup;
}
addComponent(name: string) {
let component = this.fb.group({
name: [name],
info: this.fb.group({
name: ['info_' + name],
}),
});
this.components().push(component);
}
}
and here is the template:
<hello name="{{ name }}"></hello>
<p>Start editing to see some magic happen :)</p>
<div [formGroup]="componentForm">
<input type="text" formControlName="name" />
<div style="padding-left:10px" formGroupName="definition">
<input type="text" formControlName="name" />
<div>Components</div>
<div formArrayName="components">
<div *ngFor=" let component of components().controls; let componentIndex = index " >
<div style="padding-left:10px [formGroupName]="componentIndex">
<input type="text" formControlName="name" />
<!-- 1st attempt to get to get name out of info formGroup
ERROR: Property 'info' does not exist on type 'AppComponent'-->
<!-- <div [formGroupName]="info">
<input type="text" formControlName="name" />
</div> -->
<!-- 2nd attempt
ERROR: Type 'FormGroup' is not assignable to type 'string | number'-->
<!-- <div style="padding-left:15px" [formGroupName]="componentInfo(componentIndex)" >
<input type="text" formControlName="name" />
</div> -->
</div>
</div>
</div>
</div>
</div>
<pre>{{ componentForm.value | json }}</pre>
How do I set the formGroup name for the "info" component so the "name" control shows value?
Use formGroupName
instead of [formGroupName]
.
<div formGroupName="info">
<input type="text" formControlName="name" />
</div>
Reference