A quick survey of Google App Engine and other options for hosting Node.js web applications found a few free resources if I should start venturing into web projects that require running server-side code. That survey was motivated by the Getting Started with Angular Standalone Components code lab which included instructions to host our Angular app on Google App Engine. That example application also made use of form input, an Angular topic that I knew I needed to study if I were to build useful Angular apps.
As it’s such a big part of web development, Angular’s developer guide naturally included a section on forms. The first time I read the forms overview, I got as far as learning there were two paths to building forms on Angular: “Reactive Forms” and “Template-Driven Forms”. At the time, I didn’t know enough Angular to understand how they differ, so I put the topic aside for later. I almost managed to forget about it, because the Angular “Tour of Heroes” tutorial (which I took twice) didn’t use any forms at all! The standalone components code lab reminded me it’s something I needed to get back into.
This time around, I understood their difference: Reactive forms are almost entirely specified in TypeScript code, whereas template-driven forms are mostly specified via directives in HTML markup template. Template-driven forms resemble what I saw in Vue.js with
v-model directives, allowing simple forms to be built with very little work. As scenarios get more complex, though, template-driven forms become limiting, and some features (like dynamic forms and strictly typed forms) are only available in reactive forms.
Both approaches use the
FormControl class for underlying code functionality. Each instance corresponds to a single input field in the HTML form. As forms usually have more than one input field, they are collected in a
FormControlGroup can nest inside another as desired to represent a logical structure in the form.
FormControlArray is an alternative way to group several
FormControl together, focused on dynamic organization at runtime.
To validate data user has entered into the form, Angular has a
Validators library that covers common data validation activities. Where equivalent HTML validation functionality exist, the Angular
Validators code replaces them by default. Custom data validation logic would naturally have to be written in code, but they can be attached either programmatically in a reactive form or via directives in template-driven forms.
Common control status like valid, invalid, etc. can be accessed programmatically as boolean properties on
AbstractControl (common base class for
FormControlGroup, etc.) They are also automatically reflected on the CSS classes of associated HTML input control with
.ng-invalid, etc. Handy for styling.
After reading through this developer guide, I’ve decided to focus on reactive forms for my projects in the near future based on the following reasons:
- The sample applications I’ve already looked at for reference use reactive forms. This includes the recently-completed standalone components code lab and the starter e-commerce project.
- My brain usually has an easier time reasoning about code than markup, and reactive forms are more code-centric or the two.
- Data updates in reactive forms are synchronous, versus asynchronous updates in template-driven forms. If given the choice, synchronous code is usually easier for me to debug.
- I like data type enforcement of TypeScript, and strictly-typed forms are exclusive to reactive forms. I like the ability to explicitly list expected data types (plus a null for when form is reset) via
<type|null>and declare fields expected to be optional with the “?” suffix.
While I understood this developer guide a lot better than the first time I tried reading it, there are still a lot of information I don’t understand yet. Features like asynchronous validators are topics I’ll postpone until the time when I need to learn them. I’ve already got too much theoretical Angular stuff in my head and I need to get some hands-on practice before I forget them all.