While we could endlessly debate about which option is better than the other (template-driven or reactive forms?), I want to focus instead on a more pragmatic approach and show you how you can use both approaches when you need features from reactive from within a template-driven form.
The nice thing about template-driven forms is that their definition happens entirely within HTML templates.
Making a form template-driven only requires two things: Importing the FormsModule in your app.module.ts and then using the ngModel directive on form inputs/dropdowns/checkboxes within an ****element:
Firstname:
Lastname:
That’s all you need to get the benefits of template-driven forms. With the above code, Angular will automatically add CSS classes to all form elements to reflect the current state of the form (is it valid, invalid, pristine, dirty, touched or untouched?).
A reactive form also requires a component with the Typescript definition of your form:
export class ReactiveFormComponent implements OnInit {
registerForm: FormGroup;
constructor(private formBuilder: FormBuilder) {}
ngOnInit() {
this.registerForm = this.formBuilder.group({
firstname: ['', Validators.required],
lastname: ''
})
}
}
But that’s not it, as reactive forms also require an HTML template, which seems redundant:
Firstname:
Lastname:
The main benefit of reactive-forms is that we can now subscribe to value changes or state changes on any of our form items:
this.registerForm.controls.firstname.valueChanges
.subscribe(newValue => // Do something with new value ... // );
What if I want to subscribe to values of just a couple of form inputs? Should I switch my template-driven form entirely to a reactive one just for that purpose?
Luckily, the answer is no. Let’s create a simple template-driven form:
First name:
Last name:
Submit
Now in the Typescript class of the component that defines that form, we’re going to ask Angular to give us a reference to the ngForm directive applied to the form element using the @ViewChild decorator.
This is what that code looks like:
import { Component, ViewChild} from '@angular/core';
import {NgForm} from '@angular/forms';
@Component({...})
export class AppComponent{
@ViewChild(NgForm, {static: true})
form: NgForm;
With the above code, we now have a reference to the ngForm directive, which gives us access the same valueChanges and statusChangesobservables for the entire form:
ngOnInit() {
this.form.statusChanges.subscribe(status => console.log(status));
this.form.valueChanges.subscribe(newVal => console.log(newVal));
}
And that’s it! Now we can implement reactive features in our component without having to use a full-blown reactive form.
My name is Alain Chautard. I am a Google Developer Expert in Angular, as well as founding consultant and trainer at Angular Training where I help development teams learn and become proficient with Angular.> My name is Alain Chautard. I am a Google Developer Expert in Angular, as well as founding consultant and trainer at Angular Training where I help development teams learn and become proficient with Angular.> My name is Alain Chautard. I am a Google Developer Expert in Angular, as well as founding consultant and trainer at Angular Training where I help development teams learn and become proficient with Angular.
Further reading:
☞ Angular RxJS: Observables, Observers and Operators Introduction
☞ The Pros and Cons of Angular Development
☞ Real Time Apps with TypeScript: Integrating Web Sockets, Node & Angular
☞ Angular 8 - Reactive Forms Validation Example
☞ Angular 8 User Registration and Login Example and Tutorial
☞ Understanding of ngRx with Redux in Angular
☞ Using NoSQL PouchDB and SQLite with Ionic 4 & Angular: A CRUD Example
#angular #angular-js #javascript