What is Angular FormArray and how is it different from Angular FormGroup?
We discuss everything that you simply need to know about the Angular FormArray construct, available in Angular Reactive Forms.
What is an Angular FormArray?
In Angular Reactive Forms, every form features a form model defined programmatically using the FormControl and FormGroup APIs, or alternatively using the more concise FormBuilder API, which we’ll be using throughout this guide.
Eg:
form = this.fb.group({ title: ['', { validators: [ Validators.required, Validators.minLength(5), Validators.maxLength(60) ], asyncValidators: [courseTitleValidator(this.courses)], updateOn: 'blur' }], releasedAt: [new Date(), Validators.required], category: ['BEGINNER', Validators.required], downloadsAllowed: [false, Validators.requiredTrue], longDescription: ['', [Validators.required, Validators.minLength(3)]] });
As we’ll see, employing a FormGroup, we’ll define a gaggle of related form controls, their initial values, and form validation rules, and provides property names for each field of the form.
This is possible because this is a static form with a pre-defined number of fields that are all known upfront, which is the foremost common case when it involves forms.
But what about other advanced but still frequently encountered situations where the shape is more dynamic, and where not all form fields are known upfront?
Imagine a dynamic form where form controls are added or removed to the shape by the user, counting on its interaction with the UI.
What is the difference between a FormArray and a FormGroup
Unlike our initial example where we defined the shape model using FormGroup via a call to the fb.group() API, within the case of an in-place editable table, we do not know the number of form controls upfront.
And this is often because we can not know upfront the number of rows that the table will have. The user may add an unknown number of rows using the add button, and he may remove them midway through by using the delete lesson button.
We wouldn’t be ready to define a form model using FormGroup, without knowing the precise number of rows. Also, it will be hard to give the fields pre-defined names.
But we’ll define a form model for this in-place editable table employing a FormArray instead.
A FormArray, slightly like a FormGroup, is additionally a form control container, that aggregates the values and validity state of its child components.
But unlike a FormGroup, a FormArray container doesn’t require us to know all the controls up front, also as their names.
Actually, FormArray can have an undetermined number of form controls, starting at zero. The controls can then be dynamically added and removed counting on how the user interacts with the UI.
Each control will then have a numeric position within the form controls array, rather than a unique name.
Form controls are often added or away from the form model anytime at runtime using the FormArray API.
Creating an in-place editable table using FormArray
@Component({ selector: 'form-array-example', templateUrl: 'form-array-example.component.html', styleUrls: ['form-array-example.component.scss'] }) export class FormArrayExampleComponent { form = this.fb.group({ ... other form controls ... lessons: this.fb.array([]) }); constructor(private fb:FormBuilder) {} get lessons() return this.form.controls["lessons"] as FormArray; } }
We didn’t add the opposite controls to our form, apart from the editable data table itself.
This is just to keep the example simple, but nothing would prevent us from adding the other form properties if we needed to.
In our case, all the controls inside the editable table are visiting inside the FormArray instance, built using the fb.array() API.
Initially, FormArray instance is empty and contains no form controls, It means the editable table is initially empty.
We have added to the component a getter for the lessons property, so on make it simple to access the FormArray instance in a simple and type-safe way.
Also, notice within the editable table screenshot shown earlier, that every row in the table contains two controls: a lesson title field and a lesson level (or difficulty) field.
We would like the fields to be part of the parent form of this component and affect its validity state. If a mistake occurs in the title of one of the lessons, then the entire form should be considered invalid.
For this, we are visiting create one FormGroup for each table row, which we are visiting add to it two form fields, with their own form control validators.
The FormArray API
The following are the most ordinarily used methods available in the FormArray API:
controls: this is often often often an array containing all the controls that are part of the array
length: this is often often often the total length of the array
at(index): Returns the shape control at a given array position
push(control): Adds a replacement control to the highest of the array
removeAt(index): Removes an impact at a given position of the array
getRawValue(): Gets the values of all form controls, via the control.value property of every control
When to use an Angular FormArray vs a FormGroup
When building the model of an Angular form, most of the time we’d like to use a FormGroup and not a FormArray, so that ought to be the default choice.
As we’ll see, the FormArray container is true for those rarer situations once we don’t know the number of form controls upfront or their names.
The FormArray container is true for more dynamic situations where the content of the shape is in general being defined at runtime, counting on user interaction or even backend data.
In our example, we’ve used FormArray to implement an in-place editable table, because we believe that’s its commonest use case.
In the table example, the controls within the FormArray were FormGroup instances, containing form controls themselves, but notice that this is often often often not mandatory.
A FormArray can contain any sort of controls inside it, and this includes plain form controls, FormGroup instances, and even other FormArray instances.
With FormArray, you’ll implement in Angular all sorts of advanced dynamic form scenarios, but confine mind that unless you really need the power of
FormArray, and FormGroup are going to be the correct choice for most cases.
Summary
FormArray construct is extremely powerful and comes in especially handy in situations where we want to build our form model in a more dynamic way.