Disengaged form operations | Extending of Angular FormGroup

One of the key parts that Angular provides is the Reactive Forms Module. This is a really powerful part of this framework, and it helped all of us to nicely organize and effectively operates with all of the forms we build.

Since you are here, you already know about the traditional way to build FormGroup controller that stores all of your FormControl instances.

This is an absolutely correct way to make your FormGroup instance, but in a case of a bit complex forms, along with a bunch of validation functions passed, our component has a tendency to become a messy-looking.

Especially, if we have a complex form that needs to be updated with data we fetched and/or build a kind of payload object based on the form’s values.

Let’s assume we have to make a FormGroup instance that stores a bit more controls inside, emits some custom events, and needs to be updated with already existing data:

We could simplify the patching part by using spread operators, but sometimes our DTO property names are not the same as our controls or we need to apply some data parsing before we set the values.

So, we built a simple entity editing component and it is, already, couple of dozen lines long.

Inheritance is one of the core concepts of object-oriented programming (OOP) languages. It is a mechanism where you can to derive a class from another class for a hierarchy of classes that share a set of attributes and methods.

Inspired by object-oriented programming, I thought up a different approach that helps me to isolate this bunch of form related operations by making custom and more specific form class that inheritance a FormGroup class.

At first, let’s make our derived class and set all of our controls inside:

We saw earlier, controls are set by the passing object that contains them through the FormGroup constructor. Here, we did the same thing, by calling a super method in a derived class we, actually, invoke the constructor of the base class.

Furthermore, in order to make our component cleaner, we will encapsulate the form patching process by creating a method that will operate with our DTO.

This enables us to write a single-line patching statement in our component:

Let’s make it done by moving our custom event and payload-building method in our new class:

Optionally, with this approach, we are able to keep our controls encapsulated, as well. In order to retrieve its value, we are supposed to make getter methods.

In the end, we just need to create an instance of our derived class, and it will be fully accepted by the [formGroup] directive.

Finally, we achieved a nice and clean component that is still able to operate with the whole FormGroup functionality:

Conclusion

With this approach, we can keep our code nicely-organized and improve maintenance and readability. From a testing point of view, we are able to test this part without the need for bootstrapping the whole component. I found this way pretty useful in case of, no matter what, complexity.

Thanks for reading! 👏.