Home > Software engineering >  How to patch a nested form Array?
How to patch a nested form Array?

Time:10-15

I have data coming from a form(modal) that I have to patch into another form (collapse). this is the form where the data is coming from.

formInitializer() {
    this.agrmntsForm = this.formBuilder.group({
      sales_price: new FormControl(''),
      closing_cost_support: new FormControl(''),
      financing: new FormControl(''),
      contract_date: new FormControl(''),
      inspection_period: new FormControl(''),
      closing_date: new FormControl(''),
      contacts: this.formBuilder.array([]),
    });
  } 

and this is the form I am trying to patch the data into:

mainFormInitializer() {
    this.mainForm = this.formBuilder.group({
      agreements: this.formBuilder.array([]),
    });
  }

currently I am patching the data on the first form (modal) submit. and it does patch the first array but I am having a tough time patching the nested form Array inside it.

this is the code for patching the form :

patchControls(formValue) {
    const control = <FormArray>this.mainForm.get('agreements');
    // const control2 = <FormArray>this.mainForm.get('contacts');
    console.log('form here', this.mainForm.controls.contacts);
    for (const obj of formValue) {
      const addrCtrl = this.createAgreementsGroup();
      const contactsCtrl = this.createContactsCtrl();
      addrCtrl.patchValue(obj);
      control.push(addrCtrl);
    }
  }

I have added the code to stackblitz

CodePudding user response:

You need to update below methods:

createAgreementsGroup(obj) {
 return this.formBuilder.group({
   closing_cost_support: [obj.closing_cost_support],
   closing_date: [obj.closing_date],
   contract_date: [obj.contract_date],
   financing: [obj.financing],
   inspection_period: [obj.inspection_period],
   sales_price: [obj.sales_price],
  contacts: this.formBuilder.array(this.createContactsCtrl(obj.contacts))
 });
}


createContactsCtrl(data) {
  console.log('contacts', data);
   const formArray = [];

   for(let contact of data){
     formArray.push(
       this.formBuilder.group({
         agreement_type: [contact.agreement_type],
         company: [contact.company],
         email: [contact.email],
         name: [contact.name],
         phone_number: [contact.phone_number],
      })
    );
   }
  return formArray;
 }

patchControls(data2) {
  const control = <FormArray>this.mainForm.get('agreements');

  for (const obj of data2) {
    const addrCtrl = this.createAgreementsGroup(obj);
    control.push(addrCtrl);
 }
}

Check this stackblitz

CodePudding user response:

Removed some duplicate code and you need to reinitiate agrmntsForm instead of just reset because if you add multiple contacts, its value will be reset but no of contact array entries remain while adding next time agreement form in the model.

In the below example, you can add/remove contact in the main form

To iterate contacts in the template

<div *ngFor="let contact of getContactFG(agreementIndex);let contactIndex = index" >
    <div [formGroupName]="contactIndex">
        Contact {{ contactIndex   1 }} <br />
            agreement_type :
        <input type="text" formControlName="agreement_type" /><br />
            company
        <input type="text" formControlName="company" /><br />
            email :
        <input type="text" formControlName="email" /><br />
            name:
        <input type="text" formControlName="name" /><br />
            phone_number :
        <input type="text" formControlName="phone_number" /><br />
        <button (click)="removeContact(agreementIndex, contactIndex)">
            Remove Contact
        </button>
    </div>
</div>

Helper methods to get/delete/add contact in mainForm and agrementForm

  ngOnInit() {
    this.initForms();
  }

  initForms(): void {
    this.agrmntsForm = this.getNewAgreementFG(0);
    this.mainForm = this.formBuilder.group({
      agreements: this.formBuilder.array([]),
    });
  }

  getNewAgreementFG(noOfContacts: number): FormGroup {
    const contactArr = Array.from({ length: noOfContacts }, (v, i) => i).map(
      (n) => this.createContactsCtrl()
    );
    return this.formBuilder.group({
      sales_price: [null],
      closing_cost_support: [null],
      financing: [null],
      contract_date: [null],
      inspection_period: [null],
      closing_date: [null],
      contacts: this.formBuilder.array(contactArr),
    });
  }

  getContactFGByIndex(groupIndex: number): FormArray {
    return (this.agreements().at(groupIndex) as FormGroup).get(
      'contacts'
    ) as FormArray;
  }

  addContactsMain(groupIndex: number) {
    this.getContactFGByIndex(groupIndex).push(this.createContactsCtrl());
  }

  getContactFG(groupIndex: number): FormGroup[] {
    return this.getContactFGByIndex(groupIndex).controls as FormGroup[];
  }

  removeContact(groupIndex: number, contactIndex: number): void {
    this.getContactFGByIndex(groupIndex).removeAt(contactIndex);
  }

  onSubmit() {
    this.isAgsVisible = false;
    const agrementFG = this.getNewAgreementFG(
      this.agrmntsForm.getRawValue().contacts.length
    );
    agrementFG.patchValue(this.agrmntsForm.getRawValue());
    this.agreements().push(agrementFG);
  }

  deleteAgrContact(contactIndex) {
    this.contactsArr().removeAt(contactIndex);
  }

  public agreements(): FormArray {
    return this.mainForm.get('agreements') as FormArray;
  } 

Hope this has solved all your problems

Full Angular Demo

  • Related