'Get Angular formArrayName Index Values in Template
Need help on accessing Angular formArray object values in the template. I could add and remove items from the formArray group
MINIMAL EXAMPLE
Component File
...
import { FormControl, FormGroup, FormBuilder, FormArray } from '@angular/forms';
form: FormGroup;
constructor(private fb: FormBuilder) { }
ngOnInit(): void {
this.form = this.fb.group({
candidateNumber: '',
subjectGrade: this.fb.array([])
})
}
get subjectGradeForms() {
return this.form.get('subjectGrade') as FormArray
}
addSubjectGrade() {
const subjectGrade = this.fb.group({
subject: [],
grade: []
})
this.subjectGradeForms.push(subjectGrade);
}
removeSubjectGrade(i) {
this.subjectGradeForms.removeAt(i)
}
HTML Template File
...
<form class="kt-form" id="kt_form" [formGroup]='form'>
<div class="form-group">
<label for="candidateNumber">Candidate Number</label>
<input formControlName="candidateNumber" class="form-control" type="text" required="">
</div>
<div class="row" formArrayName='subjectGrade'>
<div class="row" *ngFor="let subjectGrade of subjectGradeForms.controls; let i=index;" [formGroupName]="i">
<div class="form-group">
<label for="subject">Subject Name</label>
<select class="form-control" formControlName="subject" required="">
<option *ngFor="let subject of subjectNames" [value]="subject">{{ subject }}</option>
</select>
</div>
<div class="form-group">
<label for="grade">Subject Grade</label>
<select class="form-control" formControlName="grade" required="">
<option *ngFor="let grade of subjectGrades" [value]="grade">{{ grade }}</option>
</select>
</div>
</div>
</div>
</form>
Challenge/Problem Part [in the HTML Template File]
<div class="kt-wizard-v2__review-content">
Candidate Number: {{ form.value.candidateNumber }}<br/> <!-- works as desired with right output-->
Subject: {{ subjectGrade.value.subject[0] }}<br/> <!-- does NOT works as desired gives tscript error -->
Subject: {{ subjectGrade[0].subject }}<br/> <!-- does NOT works as desired gives tscript error -->
Subject: {{ form.value.subject[0] }}<br/> <!-- does NOT works as desired gives tscript error -->
Subject: {{ form.value.subjectGrade[0].subject }}<br/> <!-- does NOT works as desired gives tscript error -->
Subject: {{ form.value.subjectGrade }}<br/> <!-- does NOT works as desired gives tscript object as output -->
</div>
Form Value Output
value: {{ form.value | json }}
value: {"candidateNumber": "12000",
"subjectGrade": [ { "subject": "axb", "grade": "b" }, { "subject": "bxb", "grade": "b" } ]
}
Feel I'm missing something basic, but I cannot see what.
EDIT
From this form.value | json
output
{"candidateNumber": "12000",
"subjectGrade": [ { "subject": "axb", "grade": "b" },
{ "subject": "bxb", "grade": "b" } ]
}
I want to be able to get the values of the "subject" keys and the values of the "grade" keys.
So, Subject: {{ what_ever_is_here }}
should output axb
and Grade: {{ what_ever_is_here }}
should output b
. [At least for the 1st iteration]
Solution 1:[1]
Isn't your index here, on this line:
<div class="row" *ngFor="let subjectGrade of subjectGradeForms.controls; let i=index;" [formGroupName]="i">
that i
?
You must then add the button that calls the function which removes an item under that ngfor block and call:
removeSubjectGrade(i)
Is this what you meant or is your problem with the component functions?
Solution 2:[2]
This is how I implemented FormArray for checkboxes in my code,
HTML
<div formArrayName="healthQuestions">
<div
*ngFor="let questionControl of cdqRequestFG.controls.questions.controls.healthQuestions.controls; let i=index;"
nxRow>
<div class="centre-align" nxCol="12,6,4,3">
<nx-radio-group [formControlName]="i" style="display: flex;">
<nx-radio style="padding:15px;" [labelSize]="'small'" nxValue="YES">yes
</nx-radio>
<nx-radio style="padding:15px;" [labelSize]="'small'" nxValue="NO">No
</nx-radio>
</nx-radio-group>
</div>
<div nxCol="12,6,8,9">
<p style='font-size:18px; text-align: left'>{{i+1}} - {{rgaQuestions[i].description}}</p>
<!-- to display the contents of rgaQuestions, to display question number i+1 used since index begin at 0-->
</div>
</div>
</div>
Component.ts
healthQuestionsFC: FormArray;
this.healthQuestionsFC = new FormArray([], Validators.required);
// read the arry result to Model Array
//the array items are stored in array rgaQuestions[], user response for each item in this array is obtained from below loop
this.rgaQuestions.forEach(
(val, index) => {
// **getting Index value from template**
const ansC = this.healthQuestionsFC.get(index + '');
const question = new QuestionResp(val.questionId + '', ansC.value);
questionList.push(question);
});
//clear the array
clearFormArray = (formArray: FormArray) => {
while (formArray.length !== 0) {
formArray.removeAt(0);
}
}
Solution 3:[3]
For me it's work fine
get t() { return this.questions.controls.chooses as FormArray; }
t.at(i).value
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | SebastianG |
Solution 2 | |
Solution 3 | Ndiaga GUEYE |