See Migrating from 1.2 to 1.3 and AngularJS Migration Guide 1.2 to 1.3 documents first.
Change version in bower.json
We use several angular libraries: angular, angular-animate, angular-resource, etc. We have changed the versions from 1.2.26 to 1.3.14 for all angular libraries. We also specified in the resolutions to use strict version 1.3.14 for any other libraries that depend on angular
1 | "resolutions": { |
Remove 3rd party bind once plugin
Loading the website after version upgrade immediately revealed a problem with bindonce plugin.
TypeError: undefined is not a function
at e.directive.r.link (bindonce.min.js?version=185b26ab77830d1a2a331a4a6004581b8f945450:1)
Because Angular 1.3 includes bind once natively, we removed the plugin and switched a lot
of code. The code search for pasvaz.bindonce
dependency found only 4 directives that used this 3rd party
module.
Use native Angular bind once
I searched all our directive templates for attribute directives that start with bo-
letters.
Instead of bo-
syntax in these cases
1 | <span bo-text="something" class="fluid-column cell"></span> |
We used native syntax
1 | <span class="fluid-column cell">{{ ::something }}</span> |
See a few examples of one time binding in AngularJS one-time binding syntax
Disable base ref requirement
We use HTML5 push state, and do not wanted to specify the base ref in every page. Thus we have disabled this requirement, see nobase article.
Changed number input formatters
Angular 1.3 enforces number input fields to be actual numbers (as opposed to strings). Thus we got a lot
of exceptions of the form Uncaught Error: [ngModel:numfmt] Expected "-0.37" to be a number
. The problem is
the custom filters we applied to the input text field with type number returned a string view value.
To find the places with invalid filters, we paused the Chrome DevTools on unhandled exception and inspected the element variable to the number input field
1 | function numberInputType(scope, element, attr, ctrl, $sniffer, $browser) { |
We used numeral to format numbers, which converted them to strings. To allow using same format with the Angular 1.3 we convert the formatted string back into Number before returning
1 | // return formatted number |
or convert the input element from type="number"
to type="text"
.
Setup properties for binding in unit tests
Some of our directives that use isolate scope had to be tested better. We used unit tests with default undefined parent scope properties when using two-way binding. This no longer works in angular 1.3 because one cannot two-way binding to non-existing expression, see error.
1 | { |
We used to unit test the above custom directive without creating "foo" property on the parent scope. I am using kensho/ng-describe to write unit tests.
1 | ngDescribe({ |
In Angular 1.3 binding to undefined nonassignable expression is invalid and we had to create explicit parent scope
1 | ngDescribe({ |
Other thoughts
The transition was very smooth with just a little bit of syntax change due to bind once transition.