Working with forms
Last modified on Mon 04 Jan 2021

As you might already know, there are two approaches when working with forms in Angular—template-driven and reactive forms. There is a lot of great documentation on both:

The real question is which approach should you use? General reasoning is that template-driven forms should suffice if the form is simple enough (one or two elements). If the form is complex and has a lot of elements and validations, the reactive approach is easier to manage.

Going by that general reasoning, you might end up having a mix of reactive and template-driven forms in your application. For that reason, here at Infinum, we usually lean towards reactive forms. While they do have some initial overhead, forms often get more complex over time. If you start with using reactive forms, there is no need to switch from template-driven forms when they get harder to manage.

Reactive forms are also a bit easier to hook into RxJS pipelines.

NgxFormObject - our own library for working with forms!

Since we mostly use reactive forms, we've created a library, which makes things a bit easier. The library in question is ngx-form-object. Check out the project's README on GitHub to find out how to use it.

Some of the benefits of using it:

We definitely recommend trying out ngx-form-object (shameful self-promotion) if you decide to use reactive forms. We've used it on many complex projects with huge forms and it has helped us a lot!

Making your components work with forms transparently

Another topic that should be covered when talking about forms is using your own components with both reactive and template-driven forms. To use your component with forms just like you would use the input element, you will have to implement ControlValueAccessor in your component. It isn't too straight-forward and might seem complex at first glance (what is forwardRef anyway, right?), but luckily, there are some great articles which we recommend reading:

You can implement both two-way binding and ControlValueAccessor if you want your component to be usable both inside and outside a form. However, you will usually not use the same component both inside and outside a form, so implementing just ControlValueAccessor or two-way binding should be enough. Which route you choose to go depends on the use case.