Angular 4 Forms



One of my favorite features in Angular are forms. Using Angular 4 forms or Angular 5 forms are very helpful because they provide for quick validation and object mapping. Here’s how you can create a basic angular 4 form (also works with angular 2, and angular 5).

HTML

You will also notice that I am using Bootstrap for some styling, that is completely optional. Let’s look at the form HTML:

<form #myForm="ngForm" #form class=" animated fadeIn">
 <div class="form-group">
 <label for="exampleInputEmail1">First Name</label>
 <input type="email" class="form-control" aria-describedby="emailHelp" name="firstName" [(ngModel)]="student.firstName" #firstName="ngModel" required >
 <!-- <small id="emailHelp" class="form-text text-muted">We'll never share your email with anyone else.</small> -->
 <div *ngIf="firstName.errors && (firstName.dirty || firstName.touched)" class="alert alert-danger">
 <div [hidden]="!firstName.errors.required">
 Field is required!
 </div>
 </div>
 </div>
 <div class="form-group">
 <label for="exampleInputPassword1">Last Name</label>
 <input type="text" class="form-control" name="lastName" #lastName="ngModel" [(ngModel)]="student.lastName" required>
 <div *ngIf="lastName.errors && (lastName.dirty || lastName.touched)" class="alert alert-danger">
 <div [hidden]="!lastName.errors.required">
 Field is required!
 </div>
 </div>
 </div>
 <button type="submit" (click)="addStudent()" [disabled]="!myForm.valid" class="btn btn-success text-right">Add New Student</button>
 </form>

I know it looks like a hot mess, but it’s not that difficult to understand. To begin with, my form element has the line #myForm=”ngForm”. This is necessary to add if you want to use the validators in the component. You will also notice that I provided a name for the form using #form. This is not necessary, but I do it because I like to call the form’s reset function from the component. In order to do that, I need direct access to the HTML element, so I use that line so that I can set it up as a viewChild. It sounds complicated but it’s really only one line of code.

Now let’s talk about the inputs. Each input needs to have its name attribute define. Also, you need to specify a model using #someName = “ngModel”. You can look up in the angular docs as to why it is that way, but just know you need that. Also, I am using the line **[(ngModel)]=”student.firstName” **to put a two-way bind on the student object and the form input.

Now here’s the cool thing, you can add required and regex validators. I only used required in this form. You will notice that underneath each input element I have a div that shows up only if the input doesn’t meet the regex requirements or was not filled in. There is this thing called touched or dirty. Essentially, touch is if the user has entered the field. Dirty is if the field is invalid and pretty much the same thing for error.

Finally, the submit button only becomes valid when the form is completely valid. Simple right?

Component

There’s really not much to do with the component. So I will show you the relevant parts:

export class AppComponent implements OnInit {
@ViewChild('myForm') myForm:any;
title = 'app';
student: Student;
studentArray: Student[];
constructor(private toasterService: ToasterService){

this.student = new Student();
this.studentArray = [];

}

ngOnInit(){
let exampleStudent = new Student();
exampleStudent.firstName = "Sarah";
exampleStudent.lastName = "Bucket";
exampleStudent.bust = 27;
exampleStudent.waist = 25;
exampleStudent.hips = 28;
exampleStudent.inseam = 20;
exampleStudent.girth = 43;
this.calculateSize(exampleStudent);
this.studentArray.push(exampleStudent);

}

addStudent(){
this.calculateSize(this.student);
this.studentArray.push(this.student);
this.student = new Student();
this.toasterService.pop('success','Added','New Student Added');
this.myForm.reset();
}

Essentially, I create a new student object. You will also notice the viewChild stuff I mentioned earlier. This is so I can call the **form.reset() **functionality which will reset the form (and reset all dirty/touched parameters for all the inputs).