Notes about AngularJS Migrate from 1.2 to ~1.5 – The process

AngularJS: Migration process Bitacora

We are considering migrate from AJS 1.2.4 to 1.4.7 or 1.4.8, main reason of 1.4+ is because I found it 1.4+ is the  most popular and stable these days, and based on the time of release it could be a good idea to update the version.

I found interesting investigate about features we need to cover: from 1.2.4 to 1.4.0 is a big jump. The guide that illustrates migration from 1.2 to 1.3 and 1.3 to 1.4 and then 1.4.1, 1.4.2, 1.4.3, 1.4.4, 1.4.5, 1.4.6, 1.4.7 and finally 1.4.8 based on Angular Documentation.

Here is a brief of that article, common problems we can found migrating the project and dealing with legacy code (most probably from old 1.0 version).


AngularJS Versions we are planning to cover:

Version History

AngularJS 1.5.0 (this version) 9,638 Sunday, February 7, 2016
AngularJS 1.4.9 11,372 Monday, January 25, 2016
AngularJS 1.4.8 45,437 Sunday, November 22, 2015
AngularJS 1.4.7 42,468 Tuesday, October 6, 2015
AngularJS 1.4.6 19,166 Sunday, September 20, 2015
AngularJS 1.4.5 19,801 Sunday, September 6, 2015
AngularJS 1.4.4 24,026 Sunday, August 16, 2015
AngularJS 1.4.3 32,229 Thursday, July 16, 2015
AngularJS 1.4.2 13,380 Tuesday, July 7, 2015
AngularJS 1.4.1 19,566 Wednesday, June 17, 2015
AngularJS 1.4.0 22,461 Thursday, May 28, 2015
Angular JS 1.4.0-rc2 1,018 Thursday, May 14, 2015
Angular JS 1.4.0-rc1 1,081 Sunday, April 26, 2015
Angular JS 1.4.0-rc0 662 Saturday, April 11, 2015
Angular JS 1.4.0-beta6 1,288 Thursday, March 19, 2015
Angular JS 1.4.0-beta5 822 Thursday, February 26, 2015
Angular JS 1.4.0-beta4 717 Tuesday, February 10, 2015
Angular JS 1.4.0-beta3 295 Thursday, February 5, 2015
Angular JS 1.4.0-beta1 1,252 Thursday, January 22, 2015
AngularJS 1.3.18 607 Sunday, September 6, 2015
AngularJS 1.3.17 139 Sunday, September 6, 2015
AngularJS 1.3.16 1,463 Sunday, June 7, 2015
AngularJS 1.3.15 61,888 Thursday, March 19, 2015
AngularJS 1.3.14 24,519 Thursday, February 26, 2015
AngularJS 1.3.13 26,920 Tuesday, February 10, 2015
AngularJS 1.3.12 5,773 Thursday, February 5, 2015
AngularJS 1.3.11 217 Thursday, February 5, 2015
AngularJS 1.3.10 14,001 Thursday, January 22, 2015
AngularJS 1.3.9 4,491 Saturday, January 17, 2015
Angular JS 1.3.8 24,905 Sunday, December 21, 2014
Angular JS 1.3.7 3,725 Tuesday, December 16, 2014
Angular JS 1.3.6 6,062 Tuesday, December 9, 2014
Angular JS 1.3.5 5,698 Wednesday, December 3, 2014
Angular JS 1.3.4 6,515 Tuesday, November 25, 2014
Angular JS 1.3.3 11,579 Wednesday, November 19, 2014
Angular JS 1.3.2 9,306 Sunday, November 9, 2014
Angular JS 1.3.1 10,885 Sunday, November 2, 2014
Angular JS 1.3.0 17,802 Sunday, October 19, 2014
Angular JS 1.3.0-rc5 109 Sunday, October 19, 2014
Angular JS 1.3.0-rc4 810 Thursday, October 2, 2014
Angular JS 1.3.0-rc3 311 Saturday, September 27, 2014
Angular JS 1.3.0-rc2 622 Wednesday, September 17, 2014
Angular JS 1.3.0-rc1 320 Thursday, September 11, 2014
Angular JS 1.3.0-rc0 2,177 Sunday, August 31, 2014
Angular JS 1.3.0-beta9 93 Sunday, May 25, 2014
Angular JS 1.3.0-beta8 439 Sunday, May 11, 2014
Angular JS 1.3.0-beta7 481 Sunday, April 27, 2014
Angular JS 1.3.0-beta6 2,150 Tuesday, April 22, 2014
Angular JS 1.3.0-beta5 544 Monday, April 7, 2014
Angular JS 1.3.0-beta4 272 Sunday, March 30, 2014
Angular JS 1.3.0-beta3 727 Sunday, March 23, 2014
Angular JS 1.3.0-beta2 167 Tuesday, March 18, 2014
Angular JS 1.3.0-beta1 282 Monday, March 10, 2014
Angular JS 1.2.29 485 Tuesday, October 13, 2015
Angular JS 1.2.28 3,348 Tuesday, December 16, 2014
Angular JS 1.2.27 1,184 Saturday, November 22, 2014
Angular JS 1.2.26 13,953 Thursday, October 2, 2014
Angular JS 1.2.25 13,383 Wednesday, September 17, 2014
Angular JS 1.2.24 5,674 Thursday, September 11, 2014
Angular JS 1.2.23 18,333 Sunday, August 24, 2014
Angular JS 1.2.22 7,928 Thursday, August 14, 2014
Angular JS 1.2.21 15,328 Sunday, July 27, 2014
Angular JS 1.2.20 9,200 Wednesday, July 16, 2014
Angular JS 1.2.19 10,685 Wednesday, July 2, 2014
Angular JS 1.2.18 18,069 Tuesday, June 17, 2014
Angular JS 1.2.17 10,414 Sunday, June 8, 2014
Angular JS 1.2.16 58,145 Monday, April 7, 2014
Angular JS 1.2.15 9,047 Sunday, March 23, 2014
Angular JS 1.2.14 25,366 Monday, March 3, 2014
Angular JS 1.2.13 8,059 Wednesday, February 19, 2014
Angular JS 1.2.12 879 Wednesday, February 19, 2014
Angular JS 1.2.11 209 Wednesday, February 19, 2014
Angular JS 1.2.10 283 Wednesday, February 19, 2014
Angular JS 1.2.9 731 Wednesday, February 19, 2014
Last updated



Main Features 1.3 Version:
Substantial performance and speed improvements: There was a big focus on performance, with a lot of internal optimisations. References to internal benchmarks give some impressive results.
ES6 Style Promises
angular-hint: helps us writing better Angular code and makes finding very common mistakes in our code base easier
One-time bindings syntax
-$http: add xhr statusText to completeRequest callback
ngMessages: introduce the NgMessages module and directives
ngModelOptions: custom triggers and debounce of ngModel updates
ngTouch: add optional ngSwipeDisableMouse attribute to ngSwipe directives to ignore mouse events.
-injector: strict-DI mode which disables automatic function annotation
-$scope: add $watchGroup method for observing a set of expressions
No IE8 support anymore: IE8 is no longer supported.

To be aware:
-$controller will no longer look for controllers on window (following the Jhon Papa best practices we already cover this)
-You can no longer invoke .bind, .call or .apply on a function in angular expressions.
-The (deprecated) proto property does not work inside angular expressions anymor
-If you need Object.keys, make it accessible in the scope.
promise unwrapping has been removed: $parseProvider.unwrapPromises and$parseProvider.logPromiseWarnings are gone.
-$interpolate:the function returned by $interpolate no longer has a .parts array set on it.
angular.copy changes: that it applies the prototype of the original object to the copied object. Previously, angular.copy would copy properties of the original object’s prototype chain directly onto the copied object. This means that if you iterate over only the copied object’s hasOwnProperty properties, it will no longer contain the properties from the prototype.
forEach: will iterate only over the initial number of items in the array. So if items are added to the array during the iteration, these won’t be iterated over during the initial forEach call.
angular.toJson: If you expected toJson to strip these types of properties before, you will have to manually do this yourself now.
jqLite: the jQuery detach() method does not trigger the $destroy event. If you want to destroy Angular data attached to the element, use remove().
-$compile (Directives): The isolated scope of a component directive no longer leaks into the template that contains the instance of the directive. This means that you can no longer access the isolated scope from attributes on the element where the isolated directive is defined, that’s to say, requesting isolate scope and any other scope on a single element is an error.
ng-pattern: use a regular expression object as the value for the expression.


$scope.exp = ‘/abc/i’;

$scope.exp = /abc/i;


NgModelController: replace $cancelUpdate() with $rollbackViewValue and has the same meaning
-$broadcast and $emit will now reset the currentScope property of the event to null once the event finished propagating: If any code depends on asynchronously accessing their currentScope property, it should be migrated to use targetScope instead.
Testing: some deprecated features of Protractor tests no longer work:
  Prefixes ng_ and x-ng- are no longer allowed for models


// Before:
var el = element(by.binding(‘{{ foo }}’));

// After:
var el = element(by.binding(‘foo’));




var el = element(by.binding(‘{{foo}}’));

var el = element(by.binding(‘foo’));


1.3 -> 1.4


Main Features 1.4.0:

The migration jump from 1.3 to 1.4 should be relatively straightforward.


-The new parser is easier to maintain and up to 25% faster
-The whole release has a clear feeling of getting us closer to what an app will look in AngularJS 2, by enforcing some practices.
-bug fixing (around 150)
-Fixes major animation issues
-Introduces a new API for ngCookies
ngRouter -> UI-router (we are already using it)
Improved animate: ngAnimate , $animateCss, imperative CSS-based animations, new callback and promises support and anchoring.
Improved Forms: Dynamic ngMessages
$cookies service: ngCookies module replaces $cookieStore with the new $cookies service.


var config = {
path: ‘/a/b’,
domain: ‘‘,
expires: new Date(),
secure: true
$cookies.put(‘name’, ‘value’, config);
$cookies.putObject(‘name’, ‘value’, config);
$cookies.remove(‘name’, {path: ‘/a/b’});


Handle Objects 1.4+:


complements previous angular.copy and angular.extend. It does a deep copy of all properties from source to destination preserving properties in child objects. Note how we can also use multiple source objects that will be merged in order:


// angular.merge syntax (1.4+)
angular.merge(destination, source);
angular.merge(destination, source [, source]);


// 1.4+

var person1 = {

name: ‘John’,
address : {
description: ‘Oxford Street’
var person2 = {
id: 1,
address : {
postcode: ‘SW1’
var extended = angular.extend(person1, person2);
var merged = angular.merge(person1, person2);


//extended object

id: 1,
name: ‘John’,
address : {
postcode: ‘SW1’
// merged object
id: 1,
name: ‘John’,
address : {
description: ‘Oxford Street’,
postcode: ‘SW1’


filter can now take a second argument to indicate the beginning index, defaulting to 0 if not provided. If the index is negative, it will start from the end:

angular.module(‘limitToApp’, [])
.controller(‘MainCtrl’, function(){
this.letters = [‘a’, ‘b’, ‘c’, ‘d’, ‘e’, ‘f’];


Using the limit filter on letters will output the following:

{{vm.letters | limitTo:2}} // [a, b]
{{vm.letters | limitTo:2:0}} // [a, b]
{{vm.letters | limitTo:2:1}} // [b, c]
{{vm.letters | limitTo:2:-1}} // [f]
{{vm.letters | limitTo:-2:-1}} // [d, e]



A very old request was the ability to disable an option in a select, and there was no way to do it until this release. Now, you can dynamically specify if an option should be disable


<select ng-model=”modelTest”
ng-options=”customer for customer in customers”>


//Second fav:

<select ng-model=”secondFav”
ng-options=”customer disable when is modelTest(customer) for customer in customers”>


Timezones in date filter:

<p>UTC -> date | date:'short':'UTC'</p>
<p>Paris -> date | date:'short':'GMT+0200'</p>
<p>Auckland -> date | date:'short':'GMT+1300'</p>


-$timeout and $interval:

These two services can now receive additional arguments in their callbacks, to reflect what you can do natively in the browser. So if you want to pass a parameter to the callback function of $interval or $timeout, you can now do:

var sayHello = function(param){
console.log(‘Hello ‘ + param); };
$timeout(sayHello, 1000, true, ‘world!’); // Hello world!



A nice addition to the test module are the new methods:

+ they (allowing to repeat a test over a collection of values),
+ tthey (run only this test)
+ xthey (exclude this test).



it(“should test with admin”, function(){
var user = admin;
// test with admin
it(“should test with user”, function(){
var user = user;
// test with user
it(“should test with pass”, function(){
var user = pass;
// test with pass



they(“[1] Testing should $prop”, {admin: admin, user: user, pass: pass},
// will test 3 times, with user being admin, then user, pass


ngMessageFormat: Internationalization native

-filterFilter: allow array like objects to be filtered


1.4.0 -> 1.4.8


1.4.1 Improvements

  • $compile:
    • workaround for IE11 MutationObserver
    • prevent exception when using watch as isolated scope binding property in Firefox
    • assign controller return values correctly for multiple directives
  • $location: do not get caught in infinite digest in IE9 when redirecting in $locationChangeSuccess
  • $parse: set null reference properties to undefined
  • $sanitize: do not remove tabindex attribute
  • copy: do not copy the same object twice
  • forms: parse exponential notation in numberInputType directive
  • linky: allow case insensitive scheme detection
  • ngAria:
    • update aria-valuemin/max when min/max change
    • ensure boolean values for aria-hidden and aria-disabled
  • ngModel: ignore Object.prototype properties on the form validation object
  • $compile: avoid jquery data calls when there is no data
  • ngOptions:
    • do not watch properties starting with ‘ $ ‘
    • use reference check only when not using trackBy

1.4.2 Improvements

  • $browser: prevent infinite digest if changing hash when there is no hashPrefix
  • $compile:
    • throw error when requesting new and isolate scopes (async)
  • $location: allow navigating outside the original base URL
  • merge: treat dates as atomic values instead of objects.
  • ngOptions: only watch numeric properties of an array
  • orderBy: ensure correct ordering with arrays of objects and no predicate
  • ngAria: add option to disable role=button

1.4.3 Improvements

  • $animateCss: ensure animations execute if only a keyframeStyle is provided
  • loader: define isFunction (like: angualr.isFunction thing)
  • ngAnimate: ensure that orphaned elements do not throw errors when animated


1.4.4 Improvements

  • $animate:
    • leave animation callback should not overridden by follow-up animation
    • make sure to run a post-digest reflow for parentless animations
    • ensure that class-based animations are properly applied when cancelled
  • $animateCss: make sure that skipBlocking avoids the pre-emptive transition-delay styling
  • $compile:
    • don’t trigger $observer if initial value is undefined
    • ignore optional =-bound properties with empty value
  • $injector: Allows ES6 function syntax
  • $location: don’t crash if navigating outside the app base
  • $q: Use extend to avoid overwriting prototype
  • $rootScope: don’t clear phase if $apply is re-entered
  • Angular: allow unescaped = signs in values in parseKeyValue
  • httpParamSerializerJQLike: Follow jQuery for index of arrays of objects
  • i18n: by default put negative sign before currency symbol
  • injector: check that modulesToLoad isArray.
  • input: Firefox validation trigger
  • merge: regExp should not be treated as a objects when merging.
  • ng/$locale: by default put negative sign before currency symbol
  • ngAnimate:
    • always apply a preparation reflow for CSS-based animations
    • ensure that only string-based addClass/removeClass values are applied
    • ensure that parent class-based animations are never closed by their children
    • allow animations on body and root elements
    • $timeout without invokeApply
  • ngCsp: allow CSP to be configurable
  • ngModel: correct minErr usage for correct doc creation
  • ngOptions: allow empty option selection with multiple attribute
  • ngSanitize: escape the wide char quote marks in a regex in linky.js
  • $q: small $q performance optimization
  • $q when writing tests, there is no need to call $timeout.flush() to resolve a call to $q.when with a value.
  • ngAnimate: CSS classes added/removed by ngAnimate are now applied synchronously once the first digest has passed.

1.4.5 Improvements

  • $animate: $animate.enabled(false) should disable animations on $animateCss as well
  • $animateCss:
    • do not throw errors when a closing timeout is fired on a removed element
    • fix parse errors on older Android WebViews
    • properly handle cancellation timeouts for follow-up animations
    • ensure failed animations clear the internal cache
    • the transitions options delay value should be applied before class application
  • ngAnimate:
    • use requestAnimationFrame to space out child animations
    • only buffer rAF requests within the animation runners
  • ngModel: validate pattern against the viewValue
  • ngResources: support IPv6 URLs


1.4.6 Improvements

  • $animate: invalid CSS class names should not break subsequent elements
  • $browser: handle async updates to location
  • $http: propagate status -1 for timed out requests
  • $httpBackend: send null when post-data is undefined
  • $parse:
    • throw error when accessing a restricted property indirectly
    • assign returns the new value
  • angular.copy: support copying XML nodes
  • form, ngModel: correctly notify parent form when children are added
  • input: ignore min/max if they are empty on all input types
  • ngAnimateMock: $animate.flush should work for looping animations
  • ngAria: clean up tabindex usage
  • ngJq: properly detect when ng-jq is empty
  • ngModel:
    • remove reference to parentForm from removed control
    • let aliased validator directives work on any element
  • ngRepeat: add support to iterate an object’s properties even if it does not inherit from Object
  • rootScope: add support for watchCollection to watch an object which does not inherit from Object
  • select: update option if interpolated value attribute changes
  • toDebugString: change replacement string

1.4.8 Bug Fixes

  • $animate: ensure leave animation calls close callback
  • $cacheFactory: check key exists before decreasing cache size count
  • $compile:
    • bind all directive controllers correctly when using bindToController
    • evaluate against the correct scope with bindToController on new scope
    • fix scoping of transclusion directives inside replace directive
  • $http: apply transformResponse even when data is empty
  • $location: ensure $locationChangeSuccess fires even if URL ends with #
  • $parse: evaluate once simple expressions only once
  • $resource: allow XHR request to be cancelled via a timeout promise
  • $rootScope: prevent IE9 memory leak when destroying scopes
  • Angular.js: fix isArrayLike for unusual cases
  • isArrayLike: handle jQuery objects of length 0
  • jqLite:
    • deregister special mouseenter / mouseleave events correctly
    • ensure mouseenter works with svg elements on IE
  • limitTo: start at 0 if begin is negative and exceeds input length
  • merge:
    • ensure that jqlite->jqlite and DOM->DOM
    • clone elements instead of treating them like simple objects
  • ngAria: don’t add tabindex to radio and checkbox inputs
  • ngInput: change URL_REGEXP to better match RFC3987
  • ngMock: reset cache before every test
  • ngOptions:
    • skip comments and empty options when looking for options
    • override select option registration to allow compilation of empty option

Performance Improvements

  • $compile: use static jquery data method to avoid creating new instances
  • copy:
    • avoid regex in isTypedArray
    • only validate/clear if the user specifies a destination
  • merge: remove unnecessary wrapping of jqLite element


Migrating from 1.4.8 to 1.5.0+:

Angular 1.5 takes a big step towards preparing developers for a smoother transition to Angular2 in the future.

Architecturing your applications using components, multi-slot transclusion, one-way bindings in isolate scopes, using lifecycle hooks in directive controllers and relying on native ES6 features.

Because we have no plans to move to Angular 2 maybe this is not an step we want to make.


If you would like to analyze or read these changes in more detail, please refer to the Google AngularJS changelog and some others IT blogs:

One Comment

  • jose commented on July 20, 2016 Reply

    I flirted with the idea of updating one of our older projects from angular 1.2.13 to 1.5 and… bloody hell it’s not worth the trouble. It would take me six months to sort through that shit.

Leave a Reply

Your email address will not be published. Required fields are marked *

* Copy This Password *

* Type Or Paste Password Here *