Building a Reactive Form Web Component in Angular 15
I love the concept of Micro Frontends. I feel like it’s really clean and a great way to get code re-usability in a way that feels novel (to me) from other approaches I’ve seen and tried.
Reactive forms in Angular 15, along with Angular Elements make it pretty easy to get the bones of the Micro Frontend built out pretty quickly.
But First - Project Definition
I could do a simple “Hello, World!” example, but I want to go a bit deeper with the project so I can showcase a bit more of the power of this concept.
I will create a component or group of components that work together to create a ‘food selection form’ like if you were ordering something from a restaurant online.
So our form will be for a sub sandwich shop, and have the following:
4 different sub sandwiches
3 different sub sizes
Ability to pick potato chips
4 different potato chip selections
Ability to pick a drink
5 different drink selections
The form will be styled as an angular material component, and driven by the reactive form module. We will see the form able to:
Generate a payload object that represents the customer's order data
Output this form data so that it can be combined with other form elements
be reset by an external trigger
Here is the link to the repo that is used to produce these snips of the form.
Reactive Forms: An Angular Module
^ This is a real reactive form! You can select items and you’ll see the ‘stream’ output in the box with the title “Form Output:”
A reactive form, it sounds cool, but what does it actually mean?
Let’s look at a practical example:
You may have already checked out the docs from Angular. If you did and it wasn’t satisfactory, you’re probably here looking for some quick examples of how to implement these concepts. I’ll quickly describe my key points and move on to showing some code.
In my opinion, the best place to start is the item called a ‘FormControl’. Angular Forms gives us this tool to be able to give a reactive-capable entitity for each element of a form that a user can interact with.
This entity (class or class instance) gets assigned to a specific DOM element, and when the user changes anything about that specific form element, let’s say a text input, the FormControl does a lot of work invisibly.
One of the most important bits of the form control is a property called valueChanges. This thing is neat because it’s an observable, and you’ll have access to each and every keystroke from the user when:
It’s attached to an input field
that input field is the item being typed into
you are subscribed to the emitted stream from the property (observable) called valueChanges
With these steps accomplished, it’s like being plugged directly into the user’s keyboard.
Let’s check out an example of that
In that code snippet above, we can see that I have a FormGroup (another feature of Reactive Forms from angular) that contains a bunch of FormControls. Each of those form controls have a value that they initialize to.
With this step complete we have the ability to now attach these controls to DOM elements so we can get reactive behavior based on changes that occur in our forms.
Form Controls Attached
So we can see above that the formGroup is attached directly to a form element, and then within that element, we have child form elements. Those we attach via the property ‘formControlName’ which really reference the form control by it’s property name, within the form group object.
Now when the user selects something in the selection box of the sub sandwich type selection, the form emits that. If you scroll back up to the form component above, you can see that in action as the JSON beneath the component updates.
Doing something with that stream
Now that we have form controls bound to the form elements, nothing is yet happening. And it’s just because we haven’t done anything with the output. So for the sake of brevity as this post is getting rather long, I’ll go ahead and just show it being logged to console. Your creative mind will be in charge of what to do with this data stream in your app.
Above we can see that we are subscribing to the observable valueChanges, on the entire formGroup. It is possible to subscribe to an individual formControl within a group as well. But this will get the point across that we have to handle this stream of data that the Form Control is emitting.
Conclusion
We created an example of a Reactive Form in Angular 15, saw the example working live, and understood that Form Controls are objects that emit data streams, that are meant to represent the interactions users create while filling out forms.
Angular Forms are a bit complex to start, but once you are comfortable with them, I can say they are quick to implement, nice to validate, and the reactive nature makes event-driven behavior and programming easy to reason about and verify.