Angular, an open-source web development framework comes with two different ways that can help developers of any Angular app development company to work with forms. These two methods are reactive forms and template-driven forms. Here, Reactive forms help in creating a representation of a form in the component class of the application code. On the other hand, as template-driven forms are the default method to work with Angular forms, they can be used to create an internal representation of the form. To know more about Angular reactive forms, let’s go through the blog.
1. What are Angular Reactive Forms?
Reactive form objects in Angular offer synchronous access to the data value of the form model. These forms are created from observables. This means that the form input values and the data value that the user gets are bound synchronously. Every minute change in the state of a form will return a new state. This is completely different from the template-driven forms as they come with a tendency to be asynchronous.
2. Types of Angular Forms
Now, let’s go through the two types of Angular forms that are available in the market.
2.1 Template-Driven Form
A template-driven form is an approach that uses the conventional form tag to create forms in Angular. Here, the forms are automatically interpreted and created by Angular. Later on, Angular developers can add form controls with the use of the NGModel tag. With this type of Angular form, one can also use basic HTML validations to validate the fields of the form models. Template-driven forms in Angular are known as the simplest way to create forms.
2.2 Reactive Form
The reactive form is a method which is called the programming paradigm that is concerned with the propagation of change and data flows. With this type of form, Angular developers can directly manage the data flow between data models and form controls with the help of components. Reactive forms not only help in breaking the declarative approach but are also code-driven which makes creating forms simple.
3. Steps to Create Forms in Angular
Now, we will go through steps that can help developers create forms in Angular:
3.1 Pre-requisites
Before starting with the form creation steps, here are some of the pre-requisites whose basic knowledge is required from the developers who want to work with Angular reactive forms:
- HTML Form
- Form states
- HTML Form Controls
- RxJS
Step 1: Setting Up the Project
The first step is to set up the project, and for this, here we will create a default Angular project using @angular/cli. Here is the command you need for the same:
npx @angular/cli new angular-reactive-forms-example --style=css --routing=false --skip-tests |
The above command will help the developers to configure a new Angular project. It will be done with styles set to “CSS” without any routing and skipping tests.
After this, it is time to navigate the project to the directory, below is the command line for the same:
cd angular-reactive-forms-example |
In order to work with reactive forms, the Angular developers have to avoid using FormsModule and use the ReactiveFormsModule. For this, one will have to open the app.module.ts file in the code editor and then add ReactiveFormsModule to it using the below-given code:
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { ReactiveFormsModule } from '@angular/forms'; import { AppComponent } from './app.component'; @NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule, ReactiveFormsModule, ], providers: [], bootstrap: [AppComponent] }) export class AppModule { } |
After running the above code, the developer will get a new Angular project that contains ReactiveFormsModule.
Step 2: Adding a Form to the Component Template
The second step is to add a form to the component as in reactive forms, the component class contains the logic. For this, the developer will have to open the app.component.html file in the code editor and add the code below to it.
<div class="card"> <form [formGroup]="userForm" (submit)="createUser()"> <div class="form-group"> <label for="name">Name</label> <input type="text" class="form-control" formControlName="name" /> </div> <div class="form-group"> <label for="email">Email</label> <input type="text" class="form-control" formControlName="email" /> </div> <div class="form-group"> <label for="phoneNumber">Phone Number</label> <input type="text" class="form-control" formControlName="phoneNumber" /> </div> <div class="form-group"> <label for="gender">Gender</label> <select class="form-control" formControlName="gender"> <option value="male">Male</option> <option value="female">Female</option> </select> </div> <div class="form-group"> <button type="submit">Submit</button> </div> </form> </div> |
The above code will create a form that comes with four different fields name, email, phone number, and gender. Also, the developer will add a submit button with the help of the above code. This button is used to send the form after filling form fields.
Step 3: Building the Component Class
After adding the form to the component template, it is time to create the component class. Here, the developer can define individual FormControls inside FormGroup after defining FormGroup in the component class. The form control value that is added to the FormControl is during the newing stage, it will be considered as the initial data value for the field. Here is the code for the same:
import { Component, OnInit } from '@angular/core'; import { FormControl, FormGroup } from '@angular/forms'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent implements OnInit { myForm: FormGroup; ngOnInit() { this.myForm = new FormGroup({ name: new FormControl(''), email: new FormControl(''), phoneNumber: new FormControl(''), gender: new FormControl('') }); } onSubmit(form: FormGroup) { console.log('Valid?', form.valid); // true or false console.log('Name', form.value.name); console.log('Email', form.value.email); console.log('Message', form.value.message); } } |
The above code states that the onSubmit method does not communicate the form values that are submitted to the server or any other external services. It only shows how the form’s control values and validity can be accessed.
Step 4: Updating the Component Class to Use FormBuilder
The next step is to update the component class and for this, here we will use the FormBuilder class. It helps in rewriting the ngOnInit form construction. Besides this, it also enables the Angular developers to forgo all the newing of form controls and groups. To update the component class, the developer will have to open the app.component.ts file, remove FormControl, and add FormGroup in the form with the help of the FormBuilder helper. Here is how it can be done:
import { Component, OnInit } from '@angular/core'; import { FormBuilder, FormGroup } from '@angular/forms'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent implements OnInit { myForm: FormGroup; constructor(private fb: FormBuilder) {} ngOnInit() { this.myForm = this.fb.group({ name: 'Tatva User', email: '', phoneNumber: '', gender: 'male', }); } onSubmit(form: FormGroup) { console.log('Valid?', form.valid); // true or false console.log('Name', form.value.name); console.log('Email', form.value.email); console.log('Message', form.value.message); } } |
This code helps in reducing the boilerplate code amount for developing a FormGroup.
Step 5: Updating the Component Class to Use Validators
Now, let’s update the component class for using validators. Developers can add validations anytime to the element. For this, the code given below can be used.
createForm() { this.userForm = this.fb.group({ name: this.fb.control<string>('Tatva User', [Validators.required, Validators.minLength(2), Validators.pattern('^[_A-z0-9]*((-|\s)*[_A-z0-9])*$')] ), email: this.fb.control<string>('', [Validators.required, Validators.pattern('[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,3}$')] ), phoneNumber: this.fb.control<string>('', [Validators.required, Validators.maxLength(10), Validators.pattern('^[0-9]+$')] ), gender: this.fb.control<string>('male', [Validators.required] ), }); } |
Step 6: Accessing Form Value and State on the Template
After updating the component, it is time to access the Form’s state and value. A reactive form comes with different types of states like dirty, pristine, and errors. To access them, here is the code:
<div class="card"> <form [formGroup]="userForm" (submit)="createUser()"> <div class="form-group"> <label for="name">Name</label> <input type="text" class="form-control" formControlName="name" /> <ng-container *ngIf="formData['name'].errors"> <p class="error-class" *ngIf="formData['name'].hasError('required')">Name is required</p> <p class="error-class" *ngIf="formData['name'].hasError('minLength') || formData['name'].hasError('pattern')"> Enter Valid Name </p> </ng-container> </div> <div class="form-group"> <label for="email">Email</label> <input type="text" class="form-control" formControlName="email" /> <ng-container *ngIf="formData['email'].errors"> <p class="error-class" *ngIf="formData['email'].hasError('required')">Email is required</p> <p class="error-class" *ngIf="formData['email'].hasError('pattern')"> Enter Valid Email </p> </ng-container> </div> <div class="form-group"> <label for="phoneNumber">Phone Number</label> <input type="text" class="form-control" formControlName="phoneNumber" /> <ng-container *ngIf="formData['phoneNumber'].errors"> <p class="error-class" *ngIf="formData['phoneNumber'].hasError('required')">Phone number is required</p> <p class="error-class" *ngIf="formData['phoneNumber'].hasError('minLength') || formData['phoneNumber'].hasError('pattern')"> Enter Valid Phone number </p> </ng-container> </div> <div class="form-group"> <label for="gender">Gender</label> <select class="form-control" formControlName="gender"> <option value="male">Male</option> <option value="female">Female</option> </select> <ng-container *ngIf="formData['gender'].errors"> <p class="error-class" *ngIf="formData['phoneNumber'].hasError('required')">Select Gender</p> </ng-container> </div> <div class="form-group"> <button type="submit">Submit</button> </div> </form> <pre>{{ userForm.value | json }}</pre> <ng-container *ngIf="userForm"> <h4>Form States</h4> <div>Valid : {{ userForm.valid }}</div> <div>Invalid : {{ userForm.invalid }}</div> <div>Pristine : {{ userForm.pristine }}</div> <div>Dirty : {{ userForm.dirty }}</div> <div>Touched : {{ userForm.touched }}</div> </ng-container> </div> |
To check the form states of the form, here is what can be done:
- Dirty/Pristine – It can be checked to find out whether the form is modified or not.
- Valid/Invalid – It is checked to find out the form’s validity.
- Touched/Untouched – It helps in finding out whether the form is touched or untouched.
4. Conclusion
As seen in this blog, with Angular, creating forms is easy as this framework offers in-built form validation. It offers two types of forms: template-driven and reactive forms. Here we discussed how to create a simple form model. We also went through the steps that can help any developer create a dynamic form and add components along with controls & validations whenever required. To carry out all this for your client’s project the developer will require a basic understanding of HTML form control, validations, reactive forms module, and template-driven forms module in Angular.
Comments
Leave a message...