- Learn Angular 4.0 in 10 Days - Day 1
- Learn Angular 4.0 in 10 Days - Component - Day 2
- Learn Angular 4.0 in 10 Days - Data Binding - Day 3
- Learn Angular 4.0 in 10 Days - Directives - Day 4
- Learn Angular 4.0 in 10 Days - Pipes & ViewChild - Day 5
In today's web applications, a large category of front-end applications is very much form dependent, especially in the case of large enterprise type development. Most of these applications contains simply a huge or large form which contains multiple tabs, dialogs and with non – trivial business validation logic. Forms are a very important of part of the applications. In a component-based application, we always want to split a form into small and reusable pieces of code which are stored within the Smart and Dumb components. These components are normally spread over the entire application which provides several architectural benefits, including flexibility and design changes.
In Angular 4.0 Framework, we have two different mechanisms related to form-binding.
- Template Driven Form
- Reactive or Model-Driven Forms
In this article, we will discuss the Template-Driven Forms.
Angular 4 tackles forms via the famous ngModel. The instantaneous two-way data binding of ng-model in Angular 1 is really a life-saver as it allows to transparently keep in sync a form with a view model. Forms built with this directive can only be tested in an end to end test because this requires the presence of a DOM, but still, this mechanism is very useful and simple to understand. Unlike the case of AngularJs 1.0, ngModel and other form-related directives are not available by default, we need to explicitly import them in our application module. For include the form module in our application, we need to inject the FormModule in our application and bootstrapped it.
- Easy to use
- Suitable for simple scenarios and fails for complex scenarios
- Similar to angular 1.0
- Two-way data binding (using [(NgModel)] syntax)
- Minimal component code
- Automatic track of the form and its data
- Unit testing is another challenge
In this simple example we cannot really see it, but keeping the template as the source of all form validation truth is something that can become pretty hairy rather quickly.
As we add more and more validator tags to a field or when we start adding complex cross-field validations the readability of the form decreases, to the point where it will be harder to hand it off to a web designer.
The upside of this way of handling forms is its simplicity, and it is probably more than enough to build a very large range of forms.
On the downside, the form validation logic cannot be unit tested. The only way to test this logic is to run an end to end test with a browser, for example using a headless browser like PhantomJs.
While using of directives in our templates gives us the power of rapid prototyping without too much boilerplate, we are restricted in what we can do. Reactive forms, on the other hand, let us define our form through the code and give us much more flexibility and control over data validation.
- UNIT TESTABLE
Since we have the form model defined in our code, we can unit test it.
- LISTEN TO FORM AND CONTROLS CHANGES
With reactive forms, we can listen to form or control changes easily. Each form group or form control exposes a few events which we can subscribe to (e.g. statusChanges, valuesChanges, etc).
To begin, we must first ensure we are working with the right directives and the right classes in order to take advantage of procedural forms. For this, we need to ensure that the ReactiveFormsModule was imported in the bootstrap phase of the application module. This will give us access to components, directives, and providers like FormBuilder, FormGroup, and FormControl.
- import { Component, OnInit, ViewChild } from '@angular/core';
- import { NgForm } from '@angular/forms';
- @Component({
- moduleId: module.id,
- selector: 'form-demo-1',
- templateUrl: 'app.component.formdemo1.html'
- })
- export class FormDemo1Component implements OnInit {
- private formData: any = {};
- private showMessage: boolean = false;
- constructor() {
- }
- ngOnInit(): void {
- }
- registerUser(formdata: NgForm) {
- this.formData = formdata.value;
- this.showMessage = true;
- }
- }
- <h2>Template Driven Form</h2>
- <div>
- <form #signupForm="ngForm" (ngSubmit)="registerUser(signupForm)">
- <table style="width:60%;" cellpadding="5" cellspacing="5">
- <tr>
- <td style="width :40%;">
- <label for="username">User Name</label>
- </td>
- <td style="width :60%;">
- <input type="text" name="username" id="username" [(ngModel)]="username" required>
- </td>
- </tr>
- <tr>
- <td style="width :40%;">
- <label for="email">Email</label>
- </td>
- <td style="width :60%;">
- <input type="text" name="email" id="email" [(ngModel)]="email" required>
- </td>
- </tr>
- <tr>
- <td style="width :40%;">
- <label for="password">Password</label>
- </td>
- <td style="width :60%;">
- <input type="password" name="password" id="password" [(ngModel)]="password" required>
- </td>
- </tr>
- <tr>
- <td style="width :40%;"></td>
- <td style="width :60%;">
- <button type="submit">Sign Up</button>
- </td>
- </tr>
- </table>
- </form>
- <div *ngIf="showMessage">
- <strong>Thanks You {{formData.username}} for registration</strong>
- </div>
- </div>

Note that the FormControl class is assigned to similarly named fields, both on this and in the FormBuilder#group({ }) method. This is mostly for ease of access. By saving references to the FormControl instances on this, you can access the inputs in the template without having to reference the form itself. The form fields can otherwise be reached in the template by using loginForm.controls.username and loginForm.controls.password. Likewise, any instance of FormControl in this situation can access its parent group by using its .root property (e.g. username.root.controls.password). A FormControl requires two properties: an initial value and a list of validators. Right now, we have no validation.
Validating Reactive FormsBuilding from the previous login form, we can quickly and easily add validation. Angular provides many validators out of the box. They can be imported along with the rest of dependencies for procedural forms. We are using .valid and .untouched to determine if we need to show errors - while the field is required, there is no reason to tell the user that the value is wrong if the field hasn't been visited yet. For built-in validation, we are calling .hasError() on the form element, and we are passing a string which represents the validator function we included. The error message only displays if this test returns true.
Reactive Forms Custom ValidationAs useful as the built-in validators are, it is very useful to be able to include your own. Angular allows you to do just that, with minimal effort. A simple function takes the FormControl instance and returns null if everything is fine. If the test fails, it returns an object with an arbitrarily named property. The property name is what will be used for the .hasError() test.
- <div [hidden]="!password.hasError('needsExclamation')">
- Your password must have an exclamation mark!
- </div>
- import { Component, OnInit, ViewChild } from '@angular/core';
- import { Validators, FormBuilder, FormControl, FormGroup } from '@angular/forms';
- @Component({
- moduleId: module.id,
- selector: 'form-demo-2',
- templateUrl: 'app.component.formdemo2.html'
- })
- export class FormDemo2Component implements OnInit {
- private formData: any = {};
- username = new FormControl('', [
- Validators.required,
- Validators.minLength(5)
- ]);
- password = new FormControl('', [
- Validators.required,
- hasExclamationMark
- ]);
- loginForm: FormGroup = this.builder.group({
- username: this.username,
- password: this.password
- });
- private showMessage: boolean = false;
- constructor(private builder: FormBuilder) {
- }
- ngOnInit(): void {
- }
- registerUser() {
- this.formData = this.loginForm.value;
- this.showMessage = true;
- }
- }
- function hasExclamationMark(input: FormControl) {
- const hasExclamation = input.value.indexOf('!') >= 0;
- return hasExclamation ? null : { needsExclamation: true };
- }



Deepak GuptaPosted Apr 12, 2018, 2:08 AM
Nice article sir , i found lot of things here, please write left 4 days tutorials plz
Sagar Pandurang KapPosted Jan 17, 2018, 11:46 PM
Neat and clean article...
Naresh SinghalPosted Jan 17, 2018, 11:27 PM
Nice and deep explanation....Sir Debasis Saha....