$touched is the new $dirty - AngularJS Migration Guide 1.2 to 1.3

Post featured image

Quite recently the AngularJS Team released the first RELEASE CANDIDATE of AngularJS 1.3. This small AngularJS migration guide should help you if you have any problems migrating from 1.2 to 1.3. I will shortly point out which changes did break our app and then I will show an example of one of the main new features: $asyncValidators

AngularJS migration: A change that can break stuff

$location

Angular now requires a <base> tag when html5 mode of $location is enabled. Reasoning: Using html5 mode without a <base href="..."> tag makes relative links for images, links, ... relative to the current url if the browser supports the history API. However, if the browser does not support the history API Angular falls back to using the #, and then all those relative links would be broken.

Error: https://docs.angularjs.org/error/$location/nobase

Solution: [gist id=714c93492ab4d535d105]

What a great feature: async validation

We can dump a whole load of custom validation code when switching to Angular 1.3. If you know about Angular's client-side form validation and how forms work in Angular you will understand the following migration step. In general I am using a custom form group directive for showing client-side and server-side validation errors. I recommend using this, because it saves lots of HTML Code.

Hint: $touched is the new $dirty

AngularJS 1.3 uses $validators instead of $parsers + $formatters for performing validations. This means that when it comes to creating custom validators, we must first create a directive and then include ngModel in order to register the validator onto ngModel.$validators. The code below shows an example of a validator that checks if an attribute like email or username already exists while typing in an input field.

[gist id="0b32be1f7962691556b1"]

Previously, I used a method in the user controller to accomplish a custom validation with $timeout and by using ng-change on the input field. But after the upgrade I can use $asyncValidators which does basically the same.

One thing to keep in mind is that asynchronous validations will NOT run unless all of the prior normal validators (the validators present inside of ngModel.$validators) have passed. This constriction allows for the developer to prevent the validator from making excessive backend calls when the username input data is invalid.

This is why I also changed my HTML Code a bit, e.g. the username 'exists' request should only be send when the length is valid. So I added 'minlength':

 <input type="text" required name="username" ng-model="user.username" user-exists-validator minlength="4" />

You can also show an loading animation while the request is made by using the new boolean $pending:

<div ng-if="form.username.$pending"> Checking Username... </div>

I hope I could help you with this explanation how to use custom validations and dealing with AngularJS migration to 1.3.

If you need more information what changed in Angular 1.3, please see the official CHANGELOG.