Angular 2/4 Change Form Fill FormArray Controls

I am trying to implement an edit form for a model with nested attributes (FormArray). I have syntax problems, and I'm not sure if I'm on the right track. Attributes for the main form work, this is a nested form that I'm having problems with. Here is what I still have.

Here I start a group of forms:

private initForm() { this.subscription = this.expenseService.getExpense(this.id) .subscribe( expense => { this.expense = expense; this.patchForm(); } ); this.expenseEditForm = this.fb.group({ date: '', amount: '', check_number: '', debit: '', payee_id: '', notes: '', expense_expense_categories_attributes:[] }); } 

Here I correct the form for setting values ​​from an object obtained from my API.

 private patchForm() { this.expenseEditForm.setValue({ date: '', amount: this.expense.amount_cents, check_number: this.expense.check_number, debit: this.expense.debit, payee_id: '', notes: this.expense.notes, expense_expense_categories_attributes: this.fb.array([ this.setExpenseCategories(), ]) }); } 

This is where I am stuck. How I click on FormArray. If I try to click, I get an error that it does not exist in FormArray.

 private setExpenseCategories() { for ( let expenseCategories of this.expense.expense_expense_categories){ this.fb.array.push([ this.fb.group({ expense_category_id: [expenseCategories.expense_category_id, Validators.required], amount: [expenseCategories.amount_cents] ]) }); } } 

Just in case, this is necessary. Here is my html.

 <div *ngFor="let expensecategoriesCtl of expenseEditForm.controls.expense_expense_categories_attributes.controls let i = index" [formGroupName]="i" style="margin-top: 10px;"> <md-card> <md-select class="full-width-input" placeholder="Expense Category" id="expense_category_id" formControlName="expense_category_id" > <md-option *ngFor="let expenseCategory of expenseCategories" value="{{expenseCategory.id}}"> {{expenseCategory.category}} </md-option> </md-select> <md-input-container class="full-width-input"> <input mdInput placeholder="Amount" type="number" formControlName="amount"> </md-input-container> </md-card> </div> 
+10
source share
2 answers

Some changes in DeborahK's answer, as expense.expense_expense_categories contains not primitive types, but objects. Therefore, we cannot assign values ​​as is, but each object must be enclosed in a FormGroup as you tried.

Here I have a shortened version of your code:

Build the form:

 ngOnInit() { this.expenseEditForm = this.fb.group({ notes: [''], // notice below change, we need to mark it as an formArray expense_expense_categories_attributes: this.fb.array([]) }) 

Then we call patchForm in the patchForm call, just like you. This function will look like this, note we call this.setExpenseCategories from the outside:

 patchForm() { this.expenseEditForm.patchValue({ notes: this.expense.notes, }) this.setExpenseCategories() } 

Then comes the biggest change from the existing code, where we first assign the FormArray to the control variable, and then we get an iteration of your array from the backend, create a FormGroup for each object and push the object to each FormGroup :

 setExpenseCategories(){ let control = <FormArray>this.expenseEditForm.controls.expense_expense_categories_attributes; this.expense.expense_expense_categories.forEach(x => { control.push(this.fb.group(x)); }) } 

Then to the template this example without angular material:

 <form [formGroup]="expenseEditForm"> <label>Notes: </label> <input formControlName="notes" /><br> <!-- Declare formArrayName --> <div formArrayName="expense_expense_categories_attributes"> <!-- iterate formArray --> <div *ngFor="let d of expenseEditForm.get('expense_expense_categories_attributes').controls; let i=index"> <!-- Use the index for each formGroup inside the formArray --> <div [formGroupName]="i"> <label>Amount: </label> <input formControlName="amount" /> </div> </div> </div> </form> 

Finally

demonstration

+12
source

If I understand your question correctly, you might need something like this:

  // Update the data on the form this.productForm.patchValue({ productName: this.product.productName, productCode: this.product.productCode, starRating: this.product.starRating, description: this.product.description }); this.productForm.setControl('tags', this.fb.array(this.product.tags || [])); 

Here you can see the full example: https://github.com/DeborahK/Angular2-ReactiveForms in the folder updated by APM.

+1
source

Source: https://habr.com/ru/post/1267254/


All Articles