Template Driven Vs Reactive Forms

Posted By : Shubham Singh Rawat | 30-Aug-2021

Angular Forms

The form is the essentials part in any web application. Applications use forms to perform various input driven web operations like logging in, updating the user profile, submitting various kinds of user data through different types of forms like survey, contact, feedback, registration forms etc. All the data-entry tasks are done through forms. On the surface, forms seem straightforward but based on the requirements and data needs, forms can be more complex and hard to manage. Below are the reasons in support of this argument. 

  • Form inputs are used to modify data on the page as well as the server
  • Changes often need to be reflected on the other parts of the page
  • The UI needs to clearly state expectations and errors, if any
  • Dependent fields can have complex logic
  • Forms are required to be testable, irrespective of DOM selectors usage.
  • Users have a lot of leeway in what they enter, so proper validation of values is essential to make the system consistent.
  • Dependent fields can have complex logic as their modification impact other fields and their data.

 

Angular has two differenet approaches to build and process forms.

  • Template Driven Forms
  • Reactive Forms

Both capture user input events through the view, validate it and create a form/data data model to update. Both approaches uses different way to track changes in forms. 

This guide provides overview of both the approaches and make you decide which approach is better in which scenerio. It introduces the common building blocks used by both approaches and summarizes the key differences between the two approaches in the context of setup, data flow, validation and testing.

 

Template Driven Forms

Template-driven forms make use of directives in the template to create and manipulate the underlying object model. This approach is useful when we are setting up a form to get more simpler and small data such as a signup, signin form. They're not as scalable as reactive forms. Template-driven forms could be a good fit if requirements and logics are much basic. In this approach, whole logic can be managed solely in the template. All the things happen in Templates hence very little code is required in the component class. All the behaviors specification and validations are done using directives and attributes in the template.

Form handling Aspects

  1. Scalability: Template-driven forms are not as reusable as they focus on simple scenarios. They use asynchronous data flow between the view and the data model by abstracting away the underlying form API. This abstraction also affects testing so tests are more reliant on manual change detection execution to run properly, hence require more setup.
  2. Setup: Their form model is implicit as it's manage by angular itself. The directive NgModel creates and manages a Form Control instance for a given form element. We do not have direct programmatic access to the Form Control instance. Here the source of truth is Template.
  3. Testing: Writing tests with template-driven forms requires a proper knowledge of the angualr change detection process and an understanding of how directives run on each cycle as to ensure that elements are changed at the correct time.
  4. Validation: Template-driven forms are tied to directives, and must provide custom validator directives to validate forms.

Data Flow

In template-driven forms, each element is linked to a directive that manages the form model internally.

Following steps are performed in data flows when an input field's value is changed from the view.

  1. The user types value into the input element.
  2. The input element emits an event with that value.
  3. The control value accessor triggers the setValue() method on the formControl instance and then formControl instance emits the new value.
  4. Subscribers to the valueChanges observable receive the new updated value.
  5. The control value accessor also calls the viewModelUpdate() method of NgModelwhich emits a change event.
  6. Because the component template uses two-way data binding, the property in the component is updated to the value emitted by the ngModel's Change event.

Following steps are performed in data flows from model to view when an input field's value is changed programatically.

  1. The property value is updated in the component itself.
  2. Change Detection behind and during change detection, the ngOnChanges lifecycle hook is called on the NgModel directive instance as the value of one of its inputs has changed.
  3. The ngOnChanges() method pile async task in a queue to set the value for the internal FormControl instance.
  4. Change detection completes.
  5. On the next tick, set of FormControl instance value is done.
  6. FormControl instance emits the provided value through the valueChanges observable.
  7. Any subscribers to the valueChanges observable receive the new value.
  8. The control value accessor updates the form input element in the view with the latest value.

Reactive Forms

 

Reactive forms provide explicit access to the forms object model. They are more scalable, reusable, and testable and hence robust. Reactive patterns for building your application is highly required if forms are a key part of your application as they are much more efficient in handling data for complex forms.

Reactive forms are forms whose structure is defined in the component class i.e. creation of form model with Form Groups, Form Controls, and Form Arrays is done in the component class. Validation rules are also defined in the component class. Only binding to the HTML form is done in the template unlike template-driven approach where we define the logic and controls in the HTML template.

Form handling Aspects

  1. Scalability: They are more scalable as they provide direct access to the form API, and use synchronous data flow between the data and the view model, hence help in creating large-scale forms easier. Reactive forms require less setup for testing. Testing does not require deep understanding of angular change detection to properly test form updates.
  2. Setup: With reactive forms, we define the form model directly in the component class. The formControl directive links the explicitly created formControl instance to form elements in the view. Here an internal value accessor is employed.
  3. Testing: They provide a relatively easy testing strategy as they provide synchronous access to the data and form models that makes them testable without rendering the UI. In these tests, status and data are manipulated through the control without interacting with the angular change detection cycle.
  4. Validation: It define custom validators as functions that receive a control to validate.

Data Flow

In reactive forms each form element is directly linked to the form model. Updates from the view to the model and from the model to the view are synchronous and do not depend on UI rendering.

Following steps are performed in data flows when an input field's value is changed from the view.

  1. The user types a value into the input element.
  2. The form input element emits an "input" event with the provided value.
  3. The control value accessor on the form input element immediately relays the new value to the formControl instance.
  4. FormControl instance emits the new value using valueChanges observable.
  5. Subscribers to the valueChanges observable receive the new value.

Following steps are performed in data flows from model to view when an input field's value is changed programatically.

  1. The user calls the controls's setValue() method, which updates the formControl value.
  2. FormControl instance emits the new value using valueChanges observable.
  3. Subscribers to the valueChanges observable receive the new value.
  4. The control value accessor on the form input element updates the element with the new value.

About Author

Author Image
Shubham Singh Rawat

He is a technical enthusiast who has keen interest in full-stack web development. He has good experience using java(springboot) in back-end and reactjs in front-end.

Request for Proposal

Name is required

Comment is required

Sending message..