Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / AngularJs

Display Error-Messages in Angular

0.00/5 (No votes)
19 May 2015CPOL3 min read 23.5K  
Discuss three ways displaying error messages using Angular

Introduction

After set constraints for input we should consider displaying error-messages. There are three angular ways discussed in this tips: ngShow, ngIf and ngMessages.

UPDATE: My project is based on Angular v1.3.X. Anuglar has been updated to v1.4.X, the usage of ngMessages has been changed a lot!

Background

Angular offers several solutions, or rather directives, to handle this task, the popular forms are ngShow (begins in Angular v1.0.x), ngIf (begins in Angular v1.2.x) and ngMessages (begins in Angular v1.3.x).

We have discussed about the input constraints and validations in last post (constraints).

For following comparison we use the year’s input field as an example:

<code><label>Year: <input type="number" name="year" ng-min="1459" ng-max="{{currentYear}}" ng-model="book.year" ng-required="true" /></label>
</code>

The input of ngModel book.year is required, the value must be a number and the number should not less than 1459 or more than 2015 (current year as a number).

Using the code

ng-show (official document link)

The ngShow modifies CSS class onto the element, and the content in this element will be loaded together with the whole web page.

Display error-messages using ngShow:

<code><input type="number" name="year" ng-model="book.year" ng-min="1459" ng-max="{{currentYear}}" ng-required="true" />
<span ng-show="bookInfo.year.$error.required">Year is Required.</span>
<span ng-show="bookInfo.year.$error.number">Not valid number.</span>
<span ng-show="bookInfo.year.$error.min">The publish year should be after 1459.</span>
<span ng-show="bookInfo.year.$error.max">The publish year should be before {{currentYear}}.</span>
</code>

When the page is loaded, all span will also be loaded, and we can see its content “Year is required.” existed just because Angular detects that currently the input field is empty or rather the value of bookInfo.year.$error.required is true, so the content inside of span should appear. After we put some letters to the field, “Year is required.” will be hidden.

Image 1

The behavior of span with attribute ng-show="bookInfo.year.$error.number", ng-show="bookInfo.year.$error.min" and ng-show="bookInfo.year.$error.max" are same as the span with attribute ng-show="bookInfo.year.$error.required.

Please notice that the span is only be hidden but still exists in the DOM. This is exactly the different part between ngShow and ngIf.

ng-if (official document link)

The ngIf directive modifies real DOM tree. Display error-messages using ngIf:

<code><input type="number" name="year" ng-model="book.year" ng-min="1459" ng-max="{{currentYear}}" ng-required="true" />
<span ng-if="bookInfo.year.$error.required">Year is Required.</span>
<span ng-if="bookInfo.year.$error.number">Not valid number.</span>
<span ng-if="bookInfo.year.$error.min">The publish year should be after 1459.</span>
<span ng-if="bookInfo.year.$error.max">The publish year should be before {{currentYear}}.</span>
</code>

When the page is loaded, we can see its content “Year is required.” existed. It looks like using ngShow because currently the value of bookInfo.year.$error.required is true, ngIf made a clone of span and inserted it into DOM, so the content inside of span is shown. After we put some letters to the field, the value of bookInfo.year.$error.required would be false, and ngIf will remove the span so that “Year is required.” will disappear.

Image 2

The behavior of span with attribute ng-if="bookInfo.year.$error.number", ng-if="bookInfo.year.$error.min" and ng-if="bookInfo.year.$error.max" are same as the span with attribute ng-if="bookInfo.year.$error.required".

<font color="#111111" face="Segoe UI, Arial, sans-serif"><span style="font-size: 14px;">Different between ngIf and ngShow: </span></font>ngIf controlls part of the DOM elemente while ngShow changes the CSS property.

On the other hand, once all directives matching DOM element have been identified, the Angular compiler will sort the directives by their priority. ngIf has one of the hightest priority (level 600 by default), it will run first before all other lower prioritised directives. And if we use it instead of ngShow, the UI will be well speeded up1 .

ng-messages (official document link)

The ngMessages, which contains two directives ng-messages and ng-messages-include, is a new Angular module published by Angular version 1.3.x, we can now collect all errors into another template, make the project more structured. (angular-messages.js must be included first, before we want to use it)

Display error-messages using ngMessages:

<code><!-- partials/createBook.html -->
<label>Year: <input type="number" name="year" ng-model="book.year" ng-min="1459" ng-max="{{currentYear}}" ng-required="true" /></label>
<span ng-messages="bookInfo.year.$error" ng-messages-include="partials/errorMessages/errorYear.html"></span>

<!-- partials/errorMessages/errorYear.html -->
<span class="errors">
  <span ng-message="required">Year is Required.</span>
  <span ng-message="number">The YEAR should only be number like "1459" here.</span>
  <span ng-message="min">The publish year should be after 1459</span>
  <span ng-message="max">The publish year should be before {{currentYear}}</span>
</span>
</code>

The DOM behavior by using ngMessages is similar as by using ngIf. In our web application we use ng-messages-include and create a single errorYear.html file specific with all of the messages for the possible errors. This is the pro-point comparing with ngIf.

Image 3


  1. I haven’t found a tool to test the speed, the information came from a post of stackoverflow by gjoris.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)