Reactive forms give us the ability to define our form through component code. As such, it provides more flexibility and gives us more control over data validation. Once we get our hands on its basics, we can use it to handle more complex use cases.
Let's get started with an example describing its usage.
Before we start, you must import the right modules/classes and right directives to use their features.
Follow the steps in order to work with reactive forms:-
1- Import “ReactiveFormsModule” into your app.module.ts file.
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
@NgModule({
imports: [
BrowserModule,
FormsModule,
ReactiveFormsModule,
HttpModule
]
})
2- In your component you need to import the necessary form-specific functions.
import { FormGroup, FormControl, FormBuilder } from '@angular/forms';
FormGroup is a building block that keeps a check/track on the FormControl instances. FormBuilder is used to handle form control creation, and Validators are function that are added on each form control to help in validations.
export class LoginRegistrationComponent implements OnInit {
registrationForm: FormGroup;
isFormValid:boolean = true;
constructor(public fb: FormBuilder){
this.registrationForm = fb.group({
gender: ['', Validators.required],
first_name: ['', Validators.required],
last_name: ['', Validators.required],
email: ['', Validators.required],
password: ['', Validators.compose([Validators.required,Validators.minLength(6)])],
})
Here, I am making a simple Registration form with just “required” validator. I will show you how to use your custom validations like email,mobile number,name along with the angular validators in my next blog.
Explanation:-
First, we're defining registrationForm as an instance of FormGroup. Inside of the constructor, we're using dependency injection for the FormBuilder.
Then, we reference registrationForm and call the FormBuilder to control the validation of each form field we're going to create in HTML.
As you can see, you can simply pass Validators.required alone in the case of the gender,first_name,etc field, or you can pass multiple validation requirements with Validators.compose as in the case with the password.
3- Now,We’ll add a custom method submitRegistration for handling the submitted form:-
submitRegistration(isValid) {
this.isFormValid = isValid;
if(isValid) {
this.LoginRegistrationService /// import service into the component where you will write code to make requests to the server
.post('register', this.registrationModel)
.subscribe(
data => {
if(data.status) {
this.isFormError = false;
this.RegisterSuccessMsg = data.message;
this.isRegisterSuccess = true;
} else {
this.errors = data.message;
this.isFormError = true;
}
},
error => {
this.errors = JSON.stringify(error);
}
);
}else{
}
}
Your component.ts file will look like this:-
import { FormGroup, FormControl, FormBuilder } from '@angular/forms';
import { CommonService } from '../.././path;
.
.
export class LoginRegistrationComponent implements OnInit {
registrationForm: FormGroup;
isFormValid:boolean = true;
registrationModel: any = {};
constructor(public fb: FormBuilder,private LoginRegistrationService: CommonService){
this.registrationForm = fb.group({
gender: ['', Validators.required],
first_name: ['', Validators.required],
last_name: ['', Validators.required],
email: ['', Validators.required],
password: ['', Validators.compose([Validators.required,Validators.minLength(6)])],
})
ngOnInit() {
}
submitRegistration(isValid) {
this.isFormValid = isValid;
if(isValid) {
this.LoginRegistrationService
.post('register', this.registrationModel)
.subscribe(
data => {
if(data.status) {
this.isFormError = false;
this.RegisterSuccessMsg = data.message;
this.isRegisterSuccess = true;
} else {
this.errors = data.message;
this.isFormError = true;
}
},
error => {
this.errors = JSON.stringify(error);
}
);
}else{
}
}
}
3- HTML --> I have made my Html as follows. You can modify it as per your requirements.
<div class="col-sm-6">
<div class="memberSignUp">
<h2 class="text-uppercase">Sign UP</h2>
<div class='successfulRegisterMsg' *ngIf="isRegisterSuccess">{{RegisterSuccessMsg}}</div>
<form [formGroup]="registrationForm" (ngSubmit)="submitRegistration(registrationForm.valid)" novalidate>
<div class="form-group marginTB0">
<label for="email" class="labelTitle">Your Personal Information</label>
</div>
<div class="radio custom-radio form-group">
<span class="radio-inline">
<input type="radio" id="male" value="male" formControlName="gender" [(ngModel)]="registrationModel.gender" />
<label for="male" class="">Male</label>
</span>
<span class="radio-inline">
<input type="radio" id="female" value="female" formControlName="gender" [(ngModel)]="registrationModel.gender" />
<label for="female" class="">Female</label>
</span>
<div class='form-text error' *ngIf="!isFormValid || registrationForm.controls.gender.touched">
<div*ngIf="registrationForm.controls.gender.hasError('required')">{{message.validationMessage.commonMessage}}</div>
</div>
</div>
<div class="form-group form-input-group">
<input type="text" class="form-control" formControlName="first_name" (keyup)="removeErrs()" placeholder="*First Name" [(ngModel)]="registrationModel.first_name" />
<div class='form-text error' *ngIf="!isFormValid || registrationForm.controls.first_name.touched">
<div *ngIf="registrationForm.controls.first_name.hasError('required')">{{message.validationMessage.firstName}}</div>
</div>
<input type="text" class="form-control" formControlName="last_name" (keyup)="removeErrs()" placeholder="*Last Name" [(ngModel)]="registrationModel.last_name" />
<div class='form-text error' *ngIf="!isFormValid || registrationForm.controls.last_name.touched">
<div *ngIf="registrationForm.controls.last_name.hasError('required')">{{message.validationMessage.lastName}}</div>
</div>
<input type="email" class="form-control" formControlName="email" (keyup)="removeErrs()" placeholder="*Email" [(ngModel)]="registrationModel.email" />
<div class='form-text error' *ngIf="!isFormValid || registrationForm.controls.email.touched">
<div *ngIf="registrationForm.controls.email.hasError('required')">{{message.validationMessage.email}}</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label for="pwd" class="labelTitle">Your Password</label>
<input type="password" class="form-control" formControlName="password" (keyup)="removeErrs()" placeholder="*Password" [(ngModel)]="registrationModel.password" />
<div class='form-text error' *ngIf="!isFormValid || registrationForm.controls.password.touched">
<div *ngIf="registrationForm.controls.password.hasError('required')">{{message.validationMessage.password}}</div>
<div *ngIf="registrationForm.controls.password.hasError('minlength')">{{message.validationMessage.minPassword}}</div>
</div>
</div>
</div>
</div>
<button type="submit" class="btn btn-primary btn-lg btn-block">CREATE ACCOUNT
</button>
</form>
</div>
</div>
Explanation:-
1- Add the novalidate attribute of the form element prevents the behavior of the default browsers to perform their own validation and show their own error popups.
2- Used form group directive to bind the form
3- Used formControlName directive to map each form control in the template with a named form control in the model
4- Used form control states like valid,invalid,touched to work with validations and display error messages.
You can use this example as a reference to build a reactive form.
0 Comment(s)