[Angular] Working with FormArray
'FormArray' can work with array of 'FormGroup' or 'FormControl'.
form = new FormGroup({ stock: new FormArray([ new FormGroup({ product_id: new FormControl(1), quantity: new FormControl(10) }), new FormGroup({ product_id: new FormControl(12), quantity: new FormControl(90) }), ]) });
So for Javascript, we have a 'form=new FormGroup()', inside formGoup, we have a 'stock' formArray with multi formGroup inside.
In the html, we use component approach:
<stock-products (removed)="removeStock($event)" [parent]="form"> </stock-products>
We create a custom component.
Inside the component:
import { Component, Input } from '@angular/core'; import { FormGroup, FormArray } from '@angular/forms'; @Component({ selector: 'stock-products', styleUrls: ['stock-products.component.scss'], template: ` <div class="stock-product" [formGroup]="parent"> <div formArrayName="stock"> <div *ngFor="let item of stocks; let i = index;"> <div class="stock-product__content" [formGroupName]="i"> <div class="stock-product__name"> {{ item.value.product_id }} </div> <input type="number" step="10" min="10" max="1000" formControlName="quantity"> <button type="button"> Remove </button> </div> </div> </div> </div> ` }) export class StockProductsComponent { @Input() parent: FormGroup; get stocks() { return (this.parent.get('stock') as FormArray).controls; } }
First:
<div class="stock-product" [formGroup]="parent">
Tells what want to bind 'form' object passing down from the parent component.
Then to keep the same structure, we add:
<div formArrayName="stock">
Because "stock" is a FormArray.
Inside the Form array, we loop thought each form group:
<div class="stock-product__content" [formGroupName]="i">
We use the index as key to bind 'formGroupName', it actually feeling the same as work with JS array, accessing by the index.
Notice how we get 'stock' from 'form':
get stocks() { return (this.parent.get('stock') as FormArray).controls; }
Using
(this.parent.get('stock') as FormArray)
just to tell Typescrpt, this is a FormArray type.
The same as :
get stocks() { const ary = <FormArray>this.parent.get('stock'); return ary.controls; }
To add or remove from the FormArray: we have 'push' and 'removeAt' methods
addStock(stock) { const control = this.form.get('stock') as FormArray; control.push(this.createStock(stock)); } removeStock({ group, index }: { group: FormGroup, index: number }) { const control = this.form.get('stock') as FormArray; control.removeAt(index); }