Dynamic Forms in Angular with FormArray
This is the first part of the series describing the way Angular deals with dynamic and nested reactive forms
Someone said that modern web apps are basically just forms and lists. If lists are easy to grasp for any software craftsman, forms can be tough, especially if you work with some web-development framework and its opinionated patterns and tools. The topic becomes even more interesting and complicated if talk about dynamic forms, that is:
- when the form configuration object is passed from outside, and the app builds the UI based on that (using corresponding predefined setup and restrictions), or
- when user manages how many form controls the resulting form will have using CRUD controls.
In this post we are going to discuss how Angular approaches this challenge and what dedicated out-of-the-box tools does it provide to a developer.
I will not dive into differences between Template-Driven and Reactive Forms, Reactive Forms internals, form validation, error handling, form config type safety or form testing within the scope of this post as I try to make it short and narrow-focused. So it's also a good idea to have a basic grasp on these topics as a background (or consider digging deeper into the list in future).
Finally, we are going to work within a single component for brevity purposes and to make it more visual. The next part of the series is dedicated to form component decomposition.
We will develop a tiny simple Contact Form app which need to have a set of dynamically added/removed form fields (for phone numbers and email addresses).
The initial setup for this app is available at this blitz so you could play around with the code and try the described concepts yourself.
To give life to our simple HTML structure and make UI controls interactive we are going to use
ReactiveFormsModule and some of its important building blocks:
FormBuilder service allows us to compile a basic form structure inside the app component.
FormGroup class provides a skeleton for the form and its counterparts, and delivers this contraption to the UI layer using
The trickiest part of the UI is dynamic input field (
FormControl) adding and removing for phones and emails. We are going to build this feature using
FormArray class, which provides a scaffolding for homogenous
FormGroup combinations. It gives us everything we need to develop CRUD functionality for repetitive form patterns.
The diagram shows the simplified app structure and the role of all these building blocks in it.
For demo purposes we use very simple data structure here, but as you might guess, we could easily expand any of its parts, as well as the corresponding form group structure. For instance, we could add some kind of select control for phone number group of phones array (to describe its type, for instance), or add a checkbox control for email form group to make it hidden if we chose to.
The final solution is available at this blitz.