-1

I have a task to maintain the existing project. The app have a FormGroup helper which transform all the data to the FormGroup format. The FormGroup contains nested(4) FormArray and what I want to do is to update all the data of the FormGroup together all the nested FormArray from the root of the FormGroup

form: FormGroup

this.form.patchValue(dataToUpdateWithNested4FormArray)

Created plunkr: https://plnkr.co/edit/lKiCc7n2NEckQAXd?preview

plunkr; to see the output need to open console log

I have been struggling this for few days, hope anyone can help,

Thank you!

2
  • @Indraraj26 have you run the plunkr? If you click button To patch, only few data got updated and some of second array is not get update. please advice me if I missing something., thanks! Commented Apr 12, 2021 at 7:02
  • This is expected you will have to loop over data and push it to formArray Commented Apr 12, 2021 at 7:45

2 Answers 2

2

When you has a so complex FormGroup is good use auxiliar functions that help you to create the different formArrays:

setToy(data:any=null)
{
   data=data || {toy:null,brand:null}
   return new FormGroup({
     toy:new FormControl(data.toy),
     brand:new FormControl(data.brand)
   })
}
setFriend(data:any=null)
{
   data=data || {name:null,school:null,toys:null}
   return new FormGroup({
       name:new FormControl(data.name),
       school:new FormControl(data.scholl),
       toys:new FormArray(data.toys?data.toys.map(x=>this.setToy(x)):[]
                )
   })
}

setKid(data:any=null){
   data=data ||{name:null,age:0,friends:null}
   return new FormGroup({
      name:new FormControl(data.name),
      age:new FormControl(data.age),
      friends:new FormArray(data.friends?data.friends.map(x=>this.setFriend(x)):[])
   })
}

setForm(data:any=null){
   data=data ||{name:null,age:0,kids:null}
   return new FormGroup({
      name:new FormControl(data.name),
      age:new FormControl(data.age),
      kids:new FormArray(data.kids?data.kids.map(x=>this.setKid(x)):[])
   })
   
}

See how you concatenate the functions to get the arrays.

A simple

this.form=this.setForm(data)

just create a formGroup with your data. Futhermore, I imagine you want to mannage this complex formGroup. As always we manange formArray we can make functions that return the formArrays. Again see hoy one function call to another function

getKids(){
   return this.form.get('kids') as FormArray
}
getFriends(index:number){
    return this.getKids().at(index) as FormArray
}
getToys(index1:number,index2:number){
    return this.getFriends(index1).at(index2) as FormArray
}

See how you can easy add a new Toy or a new Friend or a new kid

addToy(index1:number,index2:number){
    this.getToys(index1,index2).push(this.setToy())
}
addFriend(index:number){
    this.getFriends(index).push(this.setFriend())
}
addKid(){
   this.getKids().push(this.setKid())
}

Or remove

removeToy(index1:number,index2:number,index3:number){
    this.getToys(index1,index2).removeAt(index3)
}
removeFriend(index1:number,index2:number){
    this.getFriends(index1).removeAt(index2)
}
removeKid(index:number){
   this.getKids().removeAt(index)
}

The function that return the formArray help us also to iterate in the .html

<form [formGroup]="form">
    ....
    <div *ngFor="let kid of getKids().controls;let i=index" [formGroupName]="i">
        ...
        <div *ngFor="let friend of getFriends(i).controls;let j=index" [formGroupName]="j">
        ...
           <div *ngFor="let toy of getToys(i,j).controls;let k=index" [formGroupName]="k">
             ...
          </div>
        </div>
    </div>
</form>
Sign up to request clarification or add additional context in comments.

1 Comment

haven't try with your answer but looking at your answer I got an idea how to solve my issue, thanks !
0

The reason that it fails to patch is because it doesn't create new entries in FormArray elements. To fix this, you can recreate the FormArrays in the FormGroup when patching.

patchFormGroups(formGroup: FormGroup, newData: object) {
  formGroup.patchValue(newData);
  for (let [key, value] of Object.entries(newData)) {
    const formElem = formGroup.get(key);
    if (formElem instanceof FormArray && Array.isArray(value)) {
      formElem.clear();
      for (let arrElem of value) {
        formElem.push(this.fb.control(arrElem));
      }
    }
  }
}

2 Comments

Thank you for giving the solution, I will give it a try, thanks!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.