How to Using a FormArray in a FormGroup

1.-When you use ReactiveForms, not use [(ngModel)] (is valid the “isIndividualMark” because this not belong to the formGroup

2.-A formArray can be a FormArray of FormGroups or a FormArray of FormControls

A formArray of formGroups value will be in the way

[{id:1,name:"one"},{id:2,name:"two"}]

A formArray of formControls value will be in the way

["one","two"]

3.-When we has a FormArray we use a getter to return the formArray

get questionArray(){
   return this.sectionForm.get('questions') as FormArray
}

Well, you has a formArray of formControls so the way is always the same

<!--a div with formArrayName-->
<div formArrayName="questions">
    <!--iterating over the formArray.controls using the getter-->
    <div *ngFor="let control of questionArray.controls;let i=index">
        <!--you can use the "i" to get the value of an array,e.g.-->
        {{label[i]}}
        <!--a input with formControlName-->
        <input [formControlName]="i">
    
    </div>
</div>

BTW: if we has a formArray of FormGroup the way is a bit different

<!--a div with formArrayName-->
<div formArrayName="questions">
    <!--iterating over the formArray.controls using the getter-->
        and use [formGroupName]
    <div *ngFor="let control of questionArray.controls;let i=index"
            [formGroupName]="i">

        <!--the inputs with formControlName, see that in this case 
            is not enclosed by []-->
        <input formControlName="id">
        <input formControlName="name">
    
    </div>
</div>

Update If we want to give a value to the formGroup we use pathValue, some like

this.sectionForm = new FormGroup({...})
this.sectionForm.pathValue(myObject) //<--be carefull if we has a formArray

The problem with pathValue (or setValue) is that we need add so many elements to the formArray, so we need make some like

this.sectionForm = new FormGroup({...})
this.myobject.questions.forEach(_=>{
    this.questionArray.push(new FormControl())
}
this.sectionForm.pathValue(myObject) //Now yes!

Well, exist another option I personal like, that is to make a function that return the formGroup -with data or with default values-. Some like

createGroup(data:any=null)
    data=data || {name:'',instruction:'',mark_each_qn:false,questions:null}
    return new FormGroup({
      name: new FormControl(data.name, [Validators.required]),
      instruction: new FormControl(data.instruction, [Validators.required]),
      mark_each_qn: new FormControl(data.mark_each_qn),
      questions: new FormArray(data.questions?
                  data.question.map(x=>new FormControl(x)):
                  [])
    });

See that if we has an object we can do

this.sectionForm=this.createGroup(myObject)

And if you want an empty formGroup

this.sectionForm=this.createGroup()

Leave a Comment