I want to create several select option inputs with the response of an API.
I have defined this form with a FormArray input.
this.myForm = this.fb.group({
name: [null, [Validators.required]],
details: this.fb.array([], Validators.required),
});
Then, the getter
for the detail
input as FormArray.
get detailsArr() {
return this.myForm.get('details') as FormArray;
}
I fetch data from a service and propagate the form values with the response. The response from the server for the details
is something like this:
"details": [
{ "detailName": "detail 1", "detailValue": 2},
{ "detailName": "detail 2", "detailValue": 4},
{ "detailName": "detail 3", "detailValue": 5}
]
fetchData() {
this.dataService.getData().subscribe((res) => {
// Propagate details
this.detailsArr.push(this.fb.control(res.details));
// Propagate name
this.myForm.patchValue({
name: res.name,
});
});
}
The point is, I don't know how to set the value of the details array to the details response. With the push
method I get an array inside an array, I mean:
"details": [
[
{ "detailName": "detail 1", "detailValue": 2}
]
]
The HTML is the following:
<form [formGroup]="myForm">
<div formArrayName="details">
<select *ngFor="let detail of detailsArr.controls; let i = index" [formGroupName]="i">
<option>{{ detail.detailName }}</option>
</select>
</div>
</form>
I tried with detailsArr.value
in the for loop and seems to work, but don't know why.
I just have followed this Angular official documentation, but doesn't work. I don' know if this is the correct approach to solve this problem.
CodePudding user response:
For each element in the details
array, you need to push it as FormGroup
to detailsArr
FormArray
.
addDetailFormGroup(detail: any) {
this.detailsArr.push(
this.fb.group({
detailName: detail.detailName,
detailValue: detail.detailValue,
})
);
}
fetchData() {
this.dataService.getData().subscribe((res) => {
// Propagate details
for (let detail of res.details) {
this.addDetailFormGroup(detail);
}
...
}
Updated
As clarified with Post Owner, he wants to bind the data received from the API response as the options in the <select>
element, the FormArray
shouldn't be used in his scenario. FormArray
is used when the form requires to render the element which contains multiple FormControl
or FormGroup
.
CodePudding user response:
The solution is the one posted by @Youn Shun.
I have just added some variables and inputs to control the selected value, but with this approach all works perfectly.
export class AppComponent {
name = 'Angular ' VERSION.major;
myForm: FormGroup;
details: any[];
detailSelected: any;
constructor(private fb: FormBuilder, private dataService: DataService) {}
ngOnInit() {
this.myForm = this.fb.group({
name: [null, [Validators.required]],
detailSelected: ['', Validators.required],
});
this.fetchData();
}
fetchData() {
this.dataService.getData().subscribe((res) => {
this.details = res.details;
this.myForm.patchValue({
name: res.name,
detailSelected: this.myForm.value.detailSelected,
});
});
}
}
<form [formGroup]="myForm">
Name: <input formControlName="name" />
<label for="detailSelected">Detail:</label>
<select id="detailSelected" formControlName="detailSelected">
<ng-container *ngFor="let detail of details">
<option [value]="detail.detailValue">{{ detail.detailName }}</option>
</ng-container>
</select>
<button type="submit">Submit</button>
</form>