In the Trenches – Upgrading to Angular 2

For my next article in the Converging on Full Stack Nirvana series, I took the plunge and decided to upgrade a Meteor project from Angular 1 to Angular 2.

TL;DR

  • Angular 2 is awesome, and squarely addresses significant problems with Angular 1
  • Angular 2 is still very green (as of early June, 2016)
    • Expect some bugs with Angular itself and third party components.
    • Still some gaps in the basics. g. it took days to figure out a modal dialog strategy. https://github.com/valor-software/ng2-bootstrap/issues/579
    • Unlike more mature platforms, there’s a dearth working examples once you get beyond the basics.
    • Error reporting is vastly improved but still lacking. Move your components in bit by bit.  Test frequently or risk an arcane error message due to a problem that might be in one of dozens of places.
  • It’s a lot of work to upgrade, even if you wrote your Angular 1 app in Angular 2 style. Below are some nitty-gritty pointers. (Quick Tips – Angular 1 Habits to Break)
  • Source code: https://github.com/kokokenada/for-real-cards

Angular 2 Awesomeness

Way Simpler than Angular 1

After some requisite reading (https://angular.io/docs/ts/latest/guide/), you get a sense of purity of form and simplicity that was lacking in Angular 1.

Real Improvements to Curse of Silent Failures

A principle complaint of mine about Angular 1 was the frequency that a bug in your code led to dysfunction without error.  This is way better now.  You get actual output showing what you did wrong in your template definition and often, there error message that makes sense. What a relief!

However, it still has problems to fix before error messages become a helpful dialog between framework and developer.

TypeScript

I can’t say enough about how much better using TypeScript is compared to straight JavaScript.  The IDE (in my case a rather buggy WebStorm) gives you real help in getting your types and properties names right.  This addresses one of the main productivity killers of older JavaScript stacks – hunting down typos or confused object references that a compiler should have caught.

And, you can use real inheritance just like the days of using Java.  We can start thinking in terms of inheritance, static members, is-a vs. has-a, etc.  Way better than convoluted monkey patching and other feats of magic that dominated JavaScript in the past.

RxJS and the End of Async Madness

My Angular 1 apps often had fragile start up and data observation processes as it tried to manage the async nature of web programming.

RxJS provides some clean models for handling this and I have not even started using the advanced features.  For example, you can just declare a static Subject and any observer may just latch on.

And I won’t miss debugging race conditions.

Angular 2 is Still Very Green (Early June 2016)

Jump in and start your next project with Angular 2? Hmmm.  Be careful.

Angular 2 is very close, but still leaves Angular in an awkward position.  It doesn’t make sense to start a project with Angular 1, and Angular 2 is not quite ready yet.

Bugs

Inevitable I guess. E.g. here are a couple I encountered and so far it looks, like I can work around them easily enough. https://github.com/Urigo/angular2-meteor/issues/273 and https://github.com/valor-software/ng2-dragula/issues/278.

Some Basics Are Still Missing

Productivity boost is a main reason for choosing something like Angular 2.  So, it’s disappointing when you have burn your precious time with something simple like “how do I pop up prompt or modal”.  There were some early attempts (https://github.com/shlomiassaf/angular2-modal and https://github.com/valor-software/ng2-bootstrap) but they were just not ready yet.

More generally, the styling libraries are still very much in flux.  https://github.com/valor-software/ng2-bootstrap is useful and progressing well, but not done.  Angular Material 2 is in Alpha (https://github.com/angular/material2).  Ionic 2 (http://ionicframework.com/docs/v2/) has not yet moved to Angular rc1.

Unhelpful Error Messages

After a few days of working with Angular 2, I learned to dread “TypeError: Cannot read property ‘query’ of null”.  https://github.com/angular/angular/issues/8506

This seems to mean, “you made a mistake somewhere in your app with dependency injection”.

The only effective way I had of debugging it is to do a binary search on your components.  E.g. Remove some of the components that you suspect the problem lies and rerun your app.  If the error has gone, you now know the error is somewhere in what you just removed.  Continue to search by adding or removing until you isolated the problem. <sigh>…

I had to use a similar approach to an equally unhelpful error message “Unhandled Promise rejection: Cannot set property ‘endSourceSpan’ of null”.

Lack of Working Examples

I guess we get spoiled now-a-days, and just have an expectation that stack overflow will magic up a solution to your exact problem or question.  While there’s a poor signal to noise ratio, this is pretty much the case with Angular 1.

Angular 2, however, it is much hard to find.  For example, rc1 offered a new router and deprecated the old.  It was not that easy to find good examples, especially when you want to go beyond the simplest use.  Another example is some of the more advanced features such as dynamic component creation. (I did find this though, http://blog.lacolaco.net/post/dynamic-component-creation-in-angular-2/ which was really helpful to think through the modal issue.

A High Volume of Changes

As I started my last Angular 1 project, I was careful to consider the Angular 2 migration path.  (Here’s a great read: http://teropa.info/blog/2015/10/18/refactoring-angular-apps-to-components.html)

But don’t let this give you a false sense of security that migrating to Angular 2 will be quick and easy if you follow these practices.  It’s a lot of work and there are lot of little changes you might not be expecting.

Quick Tips – Angular 1 Habits to Break

Here are some things that surprised me and tripped me up.  Remember these to save yourself some time when you upgrade.

*ngFor uses “of” not “in”

You are used to typing ng-repeat=”thing in things”.  The new syntax is, of course, *ngFor=”let thing of things”.  Don’t forget the “of” instead of the “in”.  Or else you’ll get one of the remaining confusing and misleading error message. “EXCEPTION: Error: Uncaught (in promise): Template parse errors: Property binding ngForIn not used by any directive on an embedded template”.

Forget kebob-case, now use camelCase

You’re probably in the habit of referencing your-directives-in-kebob-case-like-this.  Use camelCase in Angular 2.

Forget ControllerAs

Perhaps in preparation for this day, you dutifully used ControllerAs syntax to pave the way for Angular 2.  Well, that was just to rid you of a possible addiction to $scope. There is no ControllerAs in Angular2.  When you convert, you’ll need to remove all of your “vm.myControllerProperty” to just “myControllerProperty”.

Deal with the undefined

In Angular 1, any errors in your template were simply ignored, so {{you could get away with anything}} without any errors.  Thankfully, Angular 2 will throw when the template produces an error.  But your components will get initialized before the data is there so, after converting, you’ll frequently get “cannot read <blah> of undefined” or similar.

An *ngIf at a high level element is sometimes a nice way to protect prevent this.  Also, you can user the safe navigator operator (?.) but it doesn’t work for [(ng-modal)]. (I.e. [(ng-model)]= “obj?.key”) will throw.

No more {{interpolation}} for Attributes

In Angular 1, you could use {{}} style for defining attributes.  Well, you can’t any more.  This is a welcome change as it allows much better compile time checking.  There a lots of ways of accomplishing the same thing. ([ngClass], [ngStyle], [attr. ____], but be prepared for some substantial refactoring if you relied heavily on that technique.

Your Styling Might Break

As with many things, Angular 2 is much more structured than Angular 1, and styling is no exception.  By default, your styles will be isolated in components.   You can revert back to a more Angular 1 style by simply adding encapsulation: ViewEncapsulation.None, to your component decorator.

For more details see: https://scotch.io/tutorials/all-the-ways-to-add-css-to-angular-2-components.

A new Syntax for ng-repeat-start

If you use, ng-repeat-start and ng-repeat-end in your Angular 1 app, check out: http://stackoverflow.com/questions/34533200/ng-repeat-start-in-angular2-aka-repeat-multiple-elements-using-ngfor.

Conclusion

We’re so very close to Angular 2. When it arrives and all third party libraries arrive, it will be awesome.  Full stack nirvana here we come.

 

Advertisements

2 thoughts on “In the Trenches – Upgrading to Angular 2

  1. Thank You! I found the Angular 2 Hero’s tutorial so good…
    Everything just worked … and then I tried the Meteor ‘Parties’ tutorial …
    so bad I was losing hope (very little worked correctly) … hope it’s just too early!
    Great stuff write more!

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s