I want to create and bind a formControl for each element of the array in score
I tried to do it but I get console error :
Cannot find control with path: 'crime_types -> 0
Cannot find control with path: 'crime_types -> 1 -> score'
public resultsForm: FormGroup;
constructor(
private _formBuilder: FormBuilder,
) {
this.resultsForm = this._formBuilder.group({
crime_types: this._formBuilder.array([])
});
for (let i = 0; i < this.tasks.length; i++) {
this.formArrayCrimeType.push(
this._formBuilder.group({
psychological_tasks_id: new FormControl(this.tasks[i].id),
patients_id: new FormControl(this.patientId),
score: new FormControl('', [Validators.required]),
})
);
}
}
public get formArrayCrimeType(): FormArray {
return this.resultsForm.get("crime_types") as FormArray;
}
public getNumber(): number {
this.numb = this.numb + 1;
return this.numb;
}
Template
<ng-container formArrayName="crime_types">
<ng-container *ngFor="let task of tasks" [formGroupName]="getNumber()">
<div *ngIf="task.psychological_processes_id == process.id" class="col-12 col-md-6">
<div class="form-div">
<label for="gender" class="form-tag">{{task.description}} *</label>
<select formControlName="score" class="custom-select" required>
<option selected disabled value="">Seleccionar puntaje...</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">2</option>
</select>
</div>
</div>
</ng-container>
</ng-container>
In our case we has a "simple" formArray of FormGroups. The "difficult" is that the formArray is split in tabs, but the "structure" is always the same.
I wrote comments in the important part of the .html
<div class="section">
<div class="section__content container__shadow mx-3">
<h2 class="section__title">
{{ test.description }} <span> <i class="bx bx-test-tube"></i></span>
</h2>
<!--here declare the [formGroup]="resultForms"-->
<form *ngIf="resultsForm" autocomplete="off" [formGroup]="resultsForm">
<!--and create a div with formArrayName-->
<div formArrayName="results">
<mat-tab-group mat-align-tabs="center" #matGroup>
<mat-tab
*ngFor="let process of processes; let i = index"
label="{{ process.description }}"
>
<div class="text-center col-md-12" style="overflow: hidden;">
<h2 class="section__subtitle">{{ process.description }}</h2>
<div class="row">
<ng-container>
<!--instead iterate over tasks, we iterate
over formArray.controls
NOT over tasks (let task of tasks)
-->
<ng-container
*ngFor="let group of formArray.controls;
let i = index"
>
<!--and we use [formGroupName]="i"
I put in another div because we use this div to
show or not is "tasks[i]==process.id"
-->
<div
[formGroupName]="i"
*ngIf="tasks[i].psychological_processes_id==process.id"
class="col-12 col-md-6"
>
<div class="form-div">
<!--we use tasks[i].description-->
<label for="gender" class="form-tag"
>{{ tasks[i].description }} *</label
>
<!--in select we use formControlName="score"-->
<select
class="custom-select"
formControlName="score"
required
>
<!--see how you indicate that you should
"Seleccionar puntaje", the [value]="null"
makes that works the Validators.required
but when create the formControl we need use
score: new FormControl(null, [Validators.required]),
-->
<option selected hidden disabled [value]="null">
Seleccionar puntaje...
</option>
<!-- use [ngValue] (not only value)
if we want to get a number,
else we get a string-->
<option [ngValue]="1">1</option>
<option [ngValue]="2">2</option>
<option [ngValue]="3">3</option>
</select>
</div>
</div>
</ng-container>
</ng-container>
</div>
...button next...
...button save...
</div>
</mat-tab>
</mat-tab-group>
</div>
</form>
</div>
</div>