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!
source to share
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);
});
})
}
source to share
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)));
));
});
}
source to share