Upgrading Angular 1.2 to 1.4

We're doing it! Upgrading angular 1.2.18 to 1.4.7
There are breaking changes to fix as well as some new features to use.
Here's what I found as I upgraded.

I downloaded the zip file from angular code and then moved the files needed into app.

Here's what we've found:
1. Update all things karma: 
1.1 update your karma.conf to use latest libraries 
1.2 use latest angular-mocks.js files
I forgot this and lots of unit tests broke (moment of panic) so save yourself and update all things karma first.

2. We use ui-date for dates and the version we had failed with latest angular. I updated to latest ui-date code but found it has a known issue with manual entry.
I modified the library code to wrap in a try catch as suggested in the issue. I'd prefer not to do that and prefer to check if date is valid but such validity checking is complex.

3. we wrote a couple of directives to check before and after dates; they pushed through a change to force validators to run (even if value did not change)
 ngModelController.$setViewValue(ngModelController.$viewValue);
Now angular 1.4.7 code ignores such a change (since nothing changed..less digest cycles...a good thing!), so I refactored the our directives to just validate rather than try set which riggers validate as a side effect. I think the new way is better actually.

4. angularjs changed cookie behavior in "1.4.0-beta.6 cookie-liberation" release "$cookies no longer exposes properties that represent the current browser cookie values. Now you must explicitly the methods described above to access the cookie values. "
So this code needs to change from:
 headers: {'X-CSRFToken': $cookies['XSRF-TOKEN']},
to this:
 headers: {'X-CSRFToken': $cookies.get('XSRF-TOKEN')},

Do a search on your codebase for: "$cookies["  if you find a match then you have to fix it.

5. angular 1.3.x changed ngModelController,formController: due to 6046e14b, "ctrl.$error no longer contains entries for validators that were successful."

It broke some tests we had since its undefined, not false;
 expect(modelController.$error['email_domains']).toBe(false);
To fix I just removed that line since its nor supported any more.
Note: testing for true continues to work as before e.g.
 expect(modelController.$error['email_domains']).toBe(true);

Do a search on your codebase for: "$error["  if you find a match then you have to fix it.

Note: we continue use this to test if all is valid, that still works aok:
 expect(modelController.$valid).toBe(true);

6. Do you use angulars i18n for currency? 
If so, read on to learn more about changes: the i18n files changed in v1.4.4 pylon-requirement "ng/$locale: by default put negative sign before currency symbol (52986724, #10158)"
This change meant -999 no longer resolved to ($999) but instead resolves to -$999

To fix, I dropped in the latest i18n language files BUT then realized we made customizations in previous version of i18n files as well as customizing tmhDynamicLocale library which we also use (sigh). I investigated how to backout such customizations but its complicated so I decided to not get distracted from the angular upgrade and open a Jira to look at locale in future.

Lesson1: don't forget to add the i18n files.
Lesson2: customizing 3rd party libraries will cause you pain in the future. But you knew that didn't you ;-)

7. We had a unit test which checked for a promise having own property of then like so:
   expect(promise.hasOwnProperty('then')).toBe(true);
This no longer works as promise properties moved to the prototype in v1.3.0-beta.18 spontaneous-combustion "$q: move Deferred and Promise methods to prototypes (23bc92b1, #8300)"
Changed to this instead:
  expect(promise.then).toBeDefined();

But really, is this kind of test necessary I gotta wonder?


We have a lot of e2e automated tests and they've been helpful in finding a number of problems (e.g. #4, #3). Really pays off for this kind of thing. Not to mention our 3k unit tests which also help flush out issues.
Tip: angular comes with a property of the version of the library: angular.version.full
Rather than hardcode the version "1.4.7" (e.g. in file paths etc), you can use angular.version.full anywhere you need to refer to the angular library version.




New features to use
Its not just about getting everything to work with new angular v1.4. There are also new features to take advantage of including:

one time binding
One of the most important improvements; shipped in 1.3, here's a good post on it from Todd Moto.
Will we use going forward? Yes.
Will we go back and change everything? Only if we see a performance gain.


disable debug data
A performance improvement, read more here; makes sense to disable in Production and Staging but not development


ng-strict-di
"Strict di mode is intended to help you make sure that your code will work when minified. However, it also will force you to make sure that your injectable functions are explicitly annotated which will improve angular's performance when injecting dependencies in your injectable functions because it doesn't have to dynamically discover a function's dependencies"

We added ng-strict-di alongside our ng-app="" in the main html file. When I loaded the app I encountered 2 js errors like this:
"Error: [$injector:strictdi] function(MyService) is not using explicit annotation and cannot be invoked in strict mode"

When I looked at the code for our MyService service everything looked ok. Turns out the problem is where MyService is used. Credit to PSLs message on stack overflow.
I fixed the usages and the app loads ok without errors.


Comments

Popular posts from this blog

deep dive into Material UI TextField built by mui

angular js protractor e2e cheatsheet

react-router v6.4+ loaders, actions, forms and more