Angular 2 forms - as patchValue on a nested form group that contains an array of objects

I have a form that has the ability to add / remove rows of items. Whenever I want to go to edit my form, I run an asynchronous call to grab some data and then patch / set the values ​​of the form controls accordingly. However, everything works as expected with my item strings, when I use Angular 2 function patchValue

it only patches the form group with the first object of the object array, not all the objects.

So, for example, if my form had 3 lines of items, for example, on an invoice, only the first one is filled in. Can anyone tell me what I am doing wrong?

Here is my component functionality

constructor() {
    this.createCheckRequestForm();
}

createCheckRequestForm() {
    this.createRequestForm = this._fb.group({
      issued_date: [new Date().toISOString(), [<any>Validators.required]],
      due_date: [new Date().toISOString(), [<any>Validators.required]],
      invoice_number: ['', [<any>Validators.required]],
      how_to_send: ['Mail', [<any>Validators.required]],
      normal_processing: ['', []],
      is_corporation: ['', []],
      line_items: this._fb.array([this.initLineItem()])
    });
  }

  /**
   *  Init the line item for the form builder
   */
  initLineItem(options?) {
    return this._fb.group({
        description: ['', []],
        coding: ['', []],
        amount: ['', []],
        line_item_types: [[], []]
    });
  }


populateFormWithRequest(requestId) {
    this.formPopulationObs = this._checkRequests.getRequest(requestId).subscribe(requestData => {




      // Iterate through the line items and patch them
      let lineItems = [];
      requestData.line_items.forEach((lineItem, index) => {

        let lineItemTypes = [];
        if(lineItem.line_item_types) {
          lineItemTypes = lineItem.line_item_types;
        }

        // Separate key-store for the coding dropdown models
        this.lineItemCodings[index] = lineItem.coding;

        let lineItemObj = {
          description: lineItem.description,
          coding: lineItem.coding,
          amount: lineItem.amount,
          line_item_types: lineItemTypes,
        }
        lineItems.push(lineItemObj);
      })

      this.createRequestForm.patchValue({line_items: lineItems});
  })
}

      

If I have such an array, only the first element appears in the "patch"

[ 
 {amount: "600", coding: "-Kfxw732pfWUS5rU0TRu", description: "Cameras"},
 {amount: "600", coding: "-Kfxw732pfWUS5rU0TRu", description: "Lights"}
]

      

Thanks in advance!

+3


source to share


2 answers


Ok, so for this to work, I actually clicked the form group items on the "line_items" control that already existed. Then change the values. Here's my updated function:



populateFormWithRequest(requestId) {
    this.formPopulationObs = this._checkRequests.getRequest(requestId).subscribe(requestData => {


      // Iterate through the line items and patch them
      requestData.line_items.forEach((lineItem, index) => {

        let lineItemTypes = [];
        if(lineItem.line_item_types) {
          lineItemTypes = lineItem.line_item_types;
        }

        // Create the item obj
        let lineItemObj = {
          description: lineItem.description,
          coding: lineItem.coding,
          amount: lineItem.amount,
          line_item_types: lineItemTypes,
        }

        const control = <FormArray>this.createRequestForm.controls['line_items'];
        control.push(this.initLineItem());
        control.at(index).patchValue(lineItemObj);
      });
  })
}

      

+2


source


The same result, slightly simpler - without creating an empty element and overwriting it:



populateFormWithRequest(requestId) { 
  this.formPopulationObs = this._checkRequests.getRequest(requestId).subscribe(requestData => { 
    this.createRequestForm["line_items"] = 

requestData.line_items.forEach(itm=>(<FormArray>this.createRequestForm["line_items"]).push(this.createRequestForm.group(itm)));

)); 
}); 
}
      

Run codeHide result


0


source







All Articles