How to Create Shared Components in Angular Template-Driven and Reactive Form

Sujono
codeburst
Published in
3 min readOct 22, 2018

--

Angular form is amazing. They give you the flexibility for tackling the validation in small/medium/enterprise web application. There are two approaches for these cases:

  • Template Driven Forms, or people call it as “The Angular 1 Way”.
  • Reactive Forms, or the new Functional Reactive way.

Which one is better? It depends on your situation. They have their own advantages and disadvantages. You can use the template driven form approach if:

  • Your app only has simple validations.
  • You want to use two-way data binding.
  • You want less code in your component.
  • You want Angular form handle and track the data.

But in a large-scale application, usually we will end up needing the functionality of Reactive Driven forms for implementing more advanced use cases. Even though Reactive Driven needs more practice and code rather than Template Driven approach, it gives your more flexibility and easier unit testing.

IMO, Reactive Form is still a winner because we don’t put the validation logic inside the template, but only in component itself. With this approach, we keep our template clean. But in the end, the decision remains in your hands.

Back to our topic, How can we make a shared component (such as dropdown) for these both approaches? Angular has the answer for this by using ControlValueAccessor. It is an interface that acts as a bridge between the Angular forms API and a native element in the DOM. Any component or directive can be turned into ControlValueAccessor with two steps:

  1. Implement the ControlValueAccessor interface.
  2. Register the component as NG_VALUE_ACCESSOR provider.

For step #1, we can create an abstract class that implement the ControlValueAccessor interface. With this abstract class, we don’t need to repeat the same implementation for each override method in shared components. Next, we also create the MakeProvider method for the reusability purpose in the same file.

Abstract Value Accessor

Usually i will put this file inside the shared folder. Why? If you take a look in the Angular Official Style Guide, Shared module has one or many components, directives, and pipes that will be re-used and referenced by the components declared in other feature modules. Besides, i don’t think there will be a need for other modules to implement the AbstractValueAccessor.

Now, we can create our first shared component. For our example, we’ll create a simple dropdown component. Let’s start with the interface for the component’s input first:

Dropdown Interface

And Dropdown component:

Dropdown Component
Dropdown Template

Now, Let’s create two forms (Template and Reactive Driven) to see the result. Each form will has the dropdown component inside of it.

App Component
App Template

You can add other things that are needed in your form, such as required validation. Just remember that Template Driven and Reactive Driven has their own way to validate the form. Template Driven uses Directives and Reactive Driven uses Validators.

You can see the full implementation in here.

Conclusion

In this article, we use ControlValueAccessor to create a shared component in Angular Template Driven and Reactive Driven Form. In my workdays, I’m always looking for a better, clean, and scalable solution, so if you have any questions, feel free to leave a comment! 🙋

Resources

--

--