Support us .Net Basics C# SQL ASP.NET Aarvi MVC Slides C# Programs Subscribe Download

Angular form validation

Suggested Videos
Part 12 - Customise ngx-bootstrap datepicker | Text | Slides
Part 13 - Angular ngif directive | Text | Slides
Part 14 - Angular disable browser validation | Text | Slides

In this video and in the next few videos we will discuss Form Validation in Angular with examples. Along the way we will discuss validating textboxes, check boxes, radio buttons, dropdownlists etc. We will also discuss, how to fix one of the common error that we get when exporting NgModel into a local variable. The error that we get is, cannot assign to a reference or variable. We will discuss what causes this error and how to fix it.


To understand validation in Angular, we need to understand the following 3 sets of properties in Angular.
touched
untouched
pristine
dirty
valid
invalid


These 6 properties are available at each individual form control level and also at the form level. Let's look at these properties in action at an individual form control level. Consider the following "Full Name" field on our CreateEmployee page.

<input id="fullName" required type="text" class="form-control" name="fullName"
       [(ngModel)]="fullName" #fullName="ngModel">

Please note :
  • We have made the Full Name input field required by including required attribute on the input field. required is HTML 5 attribute. This attribute specifies that a field is required. Besides required, there are other HTML 5 validation attributes like maxlength, pattern, min, max etc. The following page has the HTML 5 validation attributes list.https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/HTML5/Constraint_validation

  • We will discuss most of these attributes with examples, in our upcoming videos. Angular uses these HTML 5 validation attributes, for validating form fields and displaying meaningful error messages to the end user.

  • We are exporting NgModel into a local variable called fullName. To do this we are using #fullName="ngModel". This variable fullName is called with different names - local variable, template variable and template reference variable.

  • At this point if you view the page in the browse you will see the following errorCannot assign to a reference or variable!

  • We get this error because, Angular generated form model creates a property with name "fullName" and we are also creating a local reference variable with the same name by exporting ngModel to #fullName. Hence we get the error - Cannot assign to a reference or variable.

  • One way to fix this error is, by giving our local template reference variable a different name other than fullName. So if we change #fullName="ngModel" to #fullNameControl="noModel" the error goes away.

  • The other way to fix this error is by using our own model instead of using the Angular auto generated form model. Notice we have our own employee model in employee.model.ts file in models folder. We will discuss using our own employee model in our upcoming videos. For now let's continue discussing the validation properties provided by Angular.
Include the following HTML table, just after the Full Name field in create-employee.component.html. Notice we are using the local template variable fullNameControl to access the 6 validation properties provided by Angular

<table border=1 style="border-collapse:collapse; font-family:Arial; table-layout: fixed">
    <tr style="background-color:rgb(170, 120, 12); font-weight: bold">
      <td colspan="3" style="padding:3px; white-space:nowrap; width:100%">
        <h4>Full Name Field</h4>
      </td>
    </tr>
    <tr style="background-color:rgb(212, 149, 13); font-weight: bold">
      <td style="padding:10px; white-space:nowrap; width:33%">
        <div>touched : {{ fullNameControl.touched }}</div>
        <div>untouched : {{ fullNameControl.untouched }}</div>
      </td>
      <td style="padding:10px; white-space:nowrap; width:33%">
        <div>pristine : {{ fullNameControl.pristine }}</div>
        <div>dirty : {{ fullNameControl.dirty }}</div>
      </td>
      <td style="padding:10px; white-space:nowrap; width:33%">
        <div>valid : {{ fullNameControl.valid }}</div>
        <div>invalid : {{ fullNameControl.invalid }}</div>
      </td>
    </tr>
  </table>

At this point, view the page in the browser and notice the following
  • touched is false and untouched is true as we did not touch the Full Name field yet. Notice when we click in the Full Name field, touched is still false and untouched is still true. These 2 properties change when the field loses focus. So when we tab out of the control, notice both the properties change as expected.
    angular form validation properties

  • Notice the pristine and dirty properties. pristine means the form control value has not been changed and dirty means the value has been changed. Notice when we type something in the Full Name field the properties change as expected. Even after we delete everything we typed, the dirty property remains true because we have changed the value in the form control.

  • Finally notice valid and invalid properties. Since we have required attribute on the Full Name field, valid is false, if we do not have anything typed in the field. The moment we type something, valid is true and invalid is false. If we delete everything we have typed, valid becomes false and invalid becomes true as expected.
We also have these same 6 properties at the form level. Notice the form tag, we are already exporting ngForm to a local template variable - employeeForm

<form #employeeForm="ngForm" (ngSubmit)="saveEmployee(employeeForm)">

We can use this template reference variable employeeForm to access the validation properties at the form level. Copy and paste the following HTML in create-employee.component.html

<table border=1 style="border-collapse:collapse; font-family:Arial; table-layout: fixed">
  <tr style="background-color:silver; font-weight: bold">
    <td colspan="3" style="padding:3px; white-space:nowrap; width:100%">
      <h4>Employee Form</h4>
    </td>
  </tr>
  <tr style="background-color:silver; font-weight: bold">
    <td style="padding:10px; white-space:nowrap; width:33%">
      <div>touched : {{ employeeForm.touched }}</div>
      <div>untouched : {{ employeeForm.untouched }}</div>
    </td>
    <td style="padding:10px; white-space:nowrap; width:33%">
      <div>pristine : {{ employeeForm.pristine }}</div>
      <div>dirty : {{ employeeForm.dirty }}</div>
    </td>
    <td style="padding:10px; white-space:nowrap; width:33%">
      <div>valid : {{ employeeForm.valid }}</div>
      <div>invalid : {{ employeeForm.invalid }}</div>
    </td>
  </tr>
</table>

Also, make the Email input field required by placing the required attribute

<input id="email" required type="text" class="form-control"
       name="email" [(ngModel)]="email">

Save the changes and view the page in the browser. 
angular form validation
  • Notice when we type "Venkat" in the Full Name input field, 
  • touched property both at the input field level and form level is set to true
  • untouched property both at the input field level and form level is set to false
  • Same is true for dirty and pristine properties
  • However, notice valid property of the Full Name field is true but the form valid property is false. This is because, Emal field is also required and we did not enter anything in the email field, so email field is invalid and as a result the form is invalid.
  • The moment we type something in the email field, the form valid property turns true.
  • So this brings us to an important conclusion - If all the form fields are valid, then the form is valid. If any of the form field is invalid the form is also invalid.
  • Along the same lines, if any of the form field is touched, the form is also marked touched and if any of the form field is dirty the form is also marked dirty.
So to check if a form field is valid
  • Include the HTML 5 validation attributes such as required for example on the input field you want to validate.
  • Export ngModel directive to local template variable
  • Finally use the template reference variable to access the validation properties like touched, dirty, valid etc.
Along the same lines, to check if the form is valid
  • Export ngForm directive to a local template reference variable
  • Then use the template reference variable to access the validation properties at the form level.
At the moment, we are not displaying any validation error messages to the user. We will discuss how to do this in our next video.

On our form, we do not want to display the validation properties and their values. So to keep out form clean, please remove the HTML from the form, that displays the validation properties and their values.

angular crud tutorial

4 comments:

  1. Nice article and easy to understand. Really help to get into a new language. Just one typo there #fullNameControl="noModel", should be ngModel. We appreciate your tutorials.

    ReplyDelete
  2. There is one typo error in the line #fullNameControl="noModel" instead of noModel it should be "ngModel". May this help someone.

    Thanks

    ReplyDelete
  3. Please update spelling in --> to #fullNameControl="noModel"
    to be ngModel

    ReplyDelete
  4. Hi Venkat,

    "Angular generated form model creates a property with name "fullName" and we are also creating a local reference variable with the same name by exporting ngModel to #fullName."

    My question here is: Instead i create a 'local reference variable' explicitly, can i use the name that angular which already created?

    ReplyDelete

It would be great if you can help share these free resources