1

I am currently working with this nested form using form array. So, I have created form as follows in editUser.ts file:

   userEditForm : FormGroup;
    
   constructor(private fb: FormBuilder){}

   ngOnInit(): void {
    this.createUserEditForm();
  }
  
  
  createUserEditForm() {
    this.userEditForm = this.fb.group(
      {
        userId: new FormControl(null),
        userName:new FormControl(null, Validators.required),
        address: new FormControl(null),
        vehicles: this.fb.array([this.createVehiclesForm()])
      }
    );
  }

  createVehiclesForm(): FormGroup {
     return this.fb.group({
      vehicleId: new FormControl(null),
      vehicleType:new FormControl(null),
      cars: new FormArray([this.createCarsForm()])
      dates:new FormArray([this.createDatesForm()])
    })
  }


  createCarsForm(): FormGroup {
    return this.fb.group({
      carId: new FormControl(null),
      name: new FormControl(null)
    })
  }
  
    createDatesForm(): FormGroup {
    return this.fb.group({
      id:new FormControl(null),
      boughtDate: new FormControl(null) 
    })
  }

I get following json response from server as a user object:

{
    "userId": "c005",
    "userName": "Charlie",
    "address": "London",
    "vehicles": [{
        "vehicleId": 19,
        "vehicleType":"Four Wheeler",
        "cars": [{
                "carId": 20,
                "name": "BMW"
            },
            {
                "carId": 21,
                "name": "Audi"
            },
            {
                "carId": 22,
                "name": "RangeRover"
            }
        ],
        "dates": [{
            "id": 23,
            "boughtDate": "2022-02-01"
        }]
    }]
}

What is the problem that I am trying to solve?

User object has list of vehicles, inside that it has another list of cars which has carId and name inside it. I am trying to create a edit functionality where I am getting above json response from sever and I trying to patch it to user object.

Some of the ways I have tried to patch data to my userEditForm are as follows:

  1. this.userEditForm.patchValue(user); //user is object received from server. I tried to patch response directly but it did not worked.

  2. user //object received from server this.userEditForm.patchValue({ userId: user.userId, userName: user.userName, address: user.address });

              let vehicles = user.vehicles;
              const formArray = new FormArray([]);
              vehicles.forEach(car => {
                formArray.push(this.fb.group({
                  vehicleId: car.vehicleId,
                  vehicleType: car.vehicleType,
                  **cars: car.cars//**  //I am not able to patch this cars list inside vehicles
                    **dates : car.dates** //same for this date list as well
    
                }))
              });
            this.userEditForm.setControl('vehicles', formArray);
    

The method that I have tried in point number 2 patch values for all the fields except that of cars and dates. So, how to patch cars or dates inside vehicle in this scenarios. What is the proper way of patching values in deep nested form having form arrays nested in other form arrays in angular? What am i doing wrong? or How that patch should be done properly for nested form arrays. I am stuck in this for couple of days now. Any kind of suggestion or solution or something that I am missing is highly appreciated. Thanks in advance.

1 Answer 1

2

FormArray needs controls(groups) inside it to patch.

Initially, cars and dates are FormArray with 1 FormGroup. If you try to patch the response directly to userEditForm & console the userEditForm.value, you will find that 1 value is patched correctly.

https://stackoverflow.com/a/70132244/10602679

enter image description here

So, for each value in the nested array of response(user), you need to create a FormGroup & then patch value to it

let vehicles = user.vehicles;
    (this.userEditForm.get('vehicles') as FormArray).clear(); //Removing initial item b/c you are creating form array with 1 initial value
    vehicles.forEach((car) => {
      const vehicleForm = this.createVehiclesForm();
      vehicleForm.patchValue(car); //Patch each vehicle object, but it will not patch the nested cars & dates FormArray.

      //Create Cars FormArray individually & patch the value
      (vehicleForm.get('cars') as FormArray).clear(); //To remove initial value
      car.cars.forEach((item) => {
        const carForm = this.createCarsForm();
        carForm.patchValue(item); //Patch individual cars item
        (vehicleForm.get('cars') as FormArray).push(carForm);
      });

      //Dates
      (vehicleForm.get('dates') as FormArray).clear();
      car.dates.forEach((item) => {
        const dateForm = this.createDatesForm();
        dateForm.patchValue(item);
        (vehicleForm.get('dates') as FormArray).push(dateForm);
      });
      (this.userEditForm.get('vehicles') as FormArray).push(vehicleForm); //Finally, push the
    });

Working Example: https://stackblitz.com/edit/angular-4vbrzj?file=src/app/app.component.ts

Sign up to request clarification or add additional context in comments.

1 Comment

As mentioned above by @Pankaj I was not setting controls inside Form Arrays. It works like charm. Thank You!!!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.