Angular2: A couple of months in

Like any other Angular 1.x developer, I have followed the evolution of the next version of the platform from its announcement through its eventual release. I was not incensed by the lack of (complete )backwards compatibility, as some seemed to be on the initial announcement; the way I saw it, it was indeed a complete rewrite intended on fixing what was missed in the 1.x version using more modern concepts, which I am all for. The 1.x project I was on was mission critical so there was no way of attempting to rewrite it in 2.0 but I prepared by adopting John Papa’s excellent 1.x style guide recommendations, which if you are not, you should (Todd Motto’s is another excellent alternative). I followed the news on each of the RC releases, practiced with one of the initial SystemJS versions of the Tour of Heroes tutorial on the official site to get a feel for the platform and Typescript until I was finally able to work on a full fledged Angular2 project. This is a summary of my experience learning and using the platform two months in.

Learning Angular2

I started from the source, so after initially doing the SystemJS Tour of Heroes, I naturally went back to do it again this time using the CLI build version, having forgotten most of what I had learned initially. The second run through was informative, helping break in some of the new concepts by contrasting them at times with the way Angular 1.x did things. Overall I found the tutorial a good way to break into the framework, although some of the concepts can take a minute to sink in.

An additional hurdle for me was also making the transition to Typescript, which outside of typing can also be compiled to include most of the ES6 features. This made the learning curve a bit more steep but as with everything I have learned in programming so far, nothing builds confidence like practice. The addition of types makes code in my opinion clearer in defining contracts when creating APIs. It looks daunting from the outside but once you get of hang of it, it becomes second nature and your brain gets better at understanding and processing the code when scanning it. Now to get to the meat of the matter, what does it feel like to work with Angular2?

Angular2 is a good/great framework

There is one reason why Angular has spread in the enterprise world the way that it has and contrary to what you might have heard with all the new frameworks popping up, it’s not going anywhere anytime soon. To build large scale enterprise application within the context of a team where knowledge has to be shared, it’s in my opinion one, if not the best frameworks out there. The addition of Typescript, like it or not, has in a way reduced the barrier of entry for those who were considered before pure backend developers. Anecdotally, friends of mine in the .Net world have found the transition to buildings UIs a lot less complicated when using Angular2. Something about types and static language developers…

To get back to what makes Angular2 a good/great (depending mainly on the type of problem you are trying to solve) framework, here is a list based on my experience:

  • Angular2 is well designed, you can tell by comparison with Angular 1.x, which was built out of the concept of providing easy two-way data binding, that lessons were learned and applied .
  • Documentation is good: with the new site, the accent is really put on getting you going as fast as possible but with access to more advanced concepts not too far away. It can be confusing and overwhelming at times, but I found it so far to be useful.
  • Component based approach: That’s the way of the future, and it has been made trivial in Angular2. It’s an easy and natural way to represent and application. The only hard part, which is not unique to Angular2 is to decide how atomic to get in the creation of components.
  • Routing: The one weak point of vanilla Angular 1.x which was easily remediated with the excellent UI Router. Now it’s a module on itself with all kinds of functionality, everything you need to handle your routing needs.
  • LifeCycle hooks: Finally Angular officialised a way to hook into initialization and finalization in a way that did not feel hackish when creating views/components (Yes I know, using .component in 1.x offers the same functionality).
  • Quirky function and component names: You loved them in 1.x, they’re back in 2. forRoot anyone?

But seriously I felt Angular2 gave me all the tools needed to be able to develop my application and even more should I want to dig deeper. There were dragons though.

Angular2 is difficult to grasp (initially)

I know you all remember the famous graphic listing the Angular 1.x learning curve, i feel like that initial curve is even steeper. As i said earlier, the introduction of Typescript makes it even more intimidating. I am a seasoned veteran, with years of JS and Angular development behind me but it took me a bit of time to get comfortable with the framework, especially in trying to use best practices when designing and implementing features. It’s nothing for the most part that going back to the documentation often and Google Fu won’t fix, but it’s not always obvious. To summarize my feeling about it, as I was struggling through the initial phases of learning, I thought about all the new developers coming to the Web Development world through self learning and all these bootcamp type of schools and wondered how the learning curve would be for them. Maybe it is a case of old dog learning new tricks but with the emergence of Typescript, ES6, RxJS and functional programming, I feel like the barrier of entry into Front End Development has been kicked up quite a notch.

Angular 1.x was famously known for it’s steep learning curve but for a complete newbie, a good preparation in Javascript would be good enough to eventually understand it and become proficient in it, but now there are new concepts (mainly related to RxJS) that have been made part of the core framework which significantly kick up the complexity level of the framework. With the case of promises and observable for example, the intent for the makers of the framework is clearly to move into the Observable direction, but for the purpose of backwards compatibility, support for Promises is still around and it is also the way to handle HTTP calls used in the basic tutorial until you go deeper. It’s a good thing and a bad thing at the same time for me because as I learned Angular2, I wanted to learn the best practices at the same time, so even though the example with the Promises made sense, from everything I had read before I knew that it was not the “best” way of going about interacting with the API but I guess it helped easing me into the framework by proposing something familiar but in hindsight I would have liked a more tear the BandAid approach to getting up to speed with Angular2.

Angular2 annoyances and gotchas

  • How do I add custom tasks to the CLI?
  • Watch out for Shadow DOM style scoping: ( :host \deep\ shall be your friend). i.e if you’re losing your mind trying to override global styles in a component, read the documentation.
  • An HTTP call returns an Observable, but the HTTP call itself won’t fire if you don’t subscribe to the returned observable. It seems obvious now but in practice, not so much.

In summary, after working with it for 2 months now, I am still a believer in the Angular way. I think the team solidly positioned Angular2 to move forward with the best that is being done in Front End development moving forward and to do so, moving away from 1.x was necessary. So far I have seen good support for the 1.x version of the framework, and applications written with it at this point are “outdated” only in your mind. Angular2 is a different approach and you should definitely consider it for your next project but be prepared for a steeper learning curve.

Advertisements

AngularJS Extensive Tutorial: Learn to Build Modern Web Apps

This tutorial will guide you through the process of creating a full-stack application. It features step-by-step instructions on how to build a fantasy football application, code snippets of the full application, and explanations on design decisions.

http://www.thinkster.io/pick/GUIDJbpIie/angularjs-tutorial-learn-to-build-modern-web-apps

 

Developing a mobile app with Phonegap, AngularJS and ExpressJS Part I

As a side project, I have embarked lately on the task of developing a mobile application with what ended up using Phonegap, AngularJS and ExpressJS. The gist of the application is to allow users to sign up and be able to share financial tips. I will document my journey along for others who are thinking of travelling down the same road, starting with my choice of technologies, this being my first attempt at building up the whole architecture from the ground up and since I am a front end developer and I wanted to leverage that experience to build a mobile app instead of going native.

Why PhoneGap and AngularJS and not Sencha Touch or Titanium?

When deciding on the initial approach to building the app, I initially thought about using Sencha Touch. I had tried Titanium before but had found it unwieldy although I like the whole integrated IDE to production setup. I work with ExtJS on a daily basis so I figured Sencha Touch would be a natural complement but after working with AngularJS, I really did want to keep getting better at it and not have to duplicate my learning by both doing Angular and Sencha Touch at the same time so i settled on PhoneGap after reading this tutorial (must read, you need to also read this here ). My time outside of work is very limited so I have little patience for frameworks with a high learning curve. I love working with AngularJS and adding Yeoman to the mix just makes it a breeze to work with so I was set on my front end tools.

Why ExpressJS?

When deciding of what framework to use for my API I initially tried Laravel, a PHP Web framework I had heard good things about it and it did not dissappoint. With the right instructions, the set up was a breeze and I had a basic API setup quickly. I liked the overall organization of the framework but at this point, I spend 90% of my time writing Javascript, so again, I wanted to stay within a single frame of mind for this project. I had always looked forward to finally trying out NodeJS , so server side Javascript it was. Given its nature, NodeJS can be unsettling because you are basically writing your own webserver, and coming from a background where you had to deals with the Apaches and Tomcats, it takes a little while to accept that new paradigm. Freedom can be overwhelming and I needed some structure to this whole new tool so I dug up ExpressJS, which is a web application framework for Node. I also decided to use MongoDB for my database, so I needed to find out how to make ExpressJS and MongoDB work nicely together, and Moongoose provided a good abstraction for interaction with my MongoDB database. Overall understanding the ExpressJS architecture, the concept of routes and middleware was the most challenging part of this part of the journey. I ran into Locomotive and I am not so far along that I can’t refactor using it as it adds convention over configuration.

API, API, API…

This is my first time building out a RESTful API as opposed to just using and it brought up considerations that I briefly wondered about before, the first one being how do I protect my API since this will be a closed system, I just want my mobile app to talk to my API. As a front end developer, those are considerations I never thought that deep on. I had to consider each strategy (Basic and Digest Authentication, API Key, OAuth, OAuth2), and how it would affect my implementation in AngularJS as well. This is the part that to a degree I am still pondering about but I am not letting me stop from moving forward.

Yeoman

Starting up was easy following Brian’s Ford instructions, I actually use Eclipse as an IDE where both my PhoneGap project and ExpressJS applications reside. There is a NodeJS plugin that exists for Eclipse that I use to run my API server initially but then I found Nodemon, which monitors my app for changes and restarts the server automatically. All of my Angular code resides in the assets folder of my PhoneGap project where I instantiated my Angular project using the yo angular generator. If you have not used Yeoman before to manage your web development projects, I strongly recommend it.

I create all my controllers, directives and services through the yo command as it also creates the proper accompanying unit tests. One small tip here, you might be wondering where yo gets the name of your app from when creating the angular module for your application and how to modify it so that you don’t have to keep changing the app name every time you create a new file? Change the “name” property in your bower.json file and yo will use a concatenation of that name and the “App” suffix to name your Angular modules.

AngularJS & Mobile Development Libraries

I am using Angular 1.1.5  as it adds a angular-mobile resource which adds better support for click events on mobile devices.  I initially thought of using Jquery Mobile even though I had a lot of apprehension about its speed but my app won’t be doing anything fancy UI wise, just presenting and collecting information. There is a plugin called the JQuery Mobile Angular Adapter which allows the two libraries to work nicely together but I could not get it going from the routing point of view, I was trying to do my application routing through AngularJS and it just was not playing nice, maybe due to my ignorance so I gave up on it and decided to stay entirely in AngularJS . I decided though to make use of the Angular Mobile Nav plug-in for my main screen and it worked as expected right out of the box with little configuration. There is though a promising project integrating JQuery Mobile and Angular called Angular JQM which instead of using adapters for JQuery mobile provides native Angular directives for JQuery Mobile, removing the need for the 3rd party libraries. As far as development itself it’s your typical Angular app so nothing new there.

NB: Doing bower install angular will get you the latest stable branch, to get the unstable branch you need to point Bower configuration for Angular dependencies to Pattern Consulting bower repo. This is what my bower.json looks like:

{
 "name": "appMobile",
 "version": "0.0.0",
 "dependencies": {
 "angular": "PatternConsulting/bower-angular#1.1.x",
 "json3": "~3.2.4",
 "jquery": "~1.9.1",
 "bootstrap-sass": "~2.3.1",
 "es5-shim": "~2.0.8",
 "angular-resource": "PatternConsulting/bower-angular#1.1.x",
 "angular-cookies": "PatternConsulting/bower-angular#1.1.x",
 "angular-sanitize": "PatternConsulting/bower-angular#1.1.x",
 "angular-mobile": "PatternConsulting/bower-angular#1.1.x",
 "angular-bootstrap": "~0.4.0",
 "angular-ui": "~0.4.0"
 },
 "devDependencies": {
 "angular-mocks": "PatternConsulting/bower-angular#1.1.x",
 "angular-scenario": "PatternConsulting/bower-angular#1.1.x"
 }
}

Another gotcha is that when trying to deploy your PhoneGap app to your phone or emulator for testing in Eclipse, you might run into an AAPT error such as:

"[2013-07-16 01:20:35 - appmobile] /projects/appmobile/assets/app/bower_components/angular-cookies/docs/partials/api/ng.directive:a.html: error: Invalid filename.  Unable to add."

This is because of the dot in the file name. Simple solution is to delete the “docs” folder in all your angular-* folders under bower_components.

Design

I have absolutely zero design skill so of course I am using Twitter Bootstrap, and the plan is to have a designer spruce it up once development is complete. One thing I have noticed is that I find the height of text inputs to be too small. Holly Schinsky in her excellent introductory article mentioned Topcoat which I had never heard of before, and it looks good so who knows, I might give it a run on a feature branch.

Summary

The process has been interesting to say the least, and it leads sometimes to second guess myself but that is the process of learning. I will keep up updated as of my progress, issues and findings in subsequent posts.

AngularJS: Watch out for HTML comments in those templates!

One day, using

replace:true

in your directive configuration might get you a :

Error: Template must have exactly one root element. was:<your root element>…

error whether you’re providing a template string or loading through templateUrl. I went back and double checked my HTML and it looks like I indeed had only a single root element in my template but lo and behold, that root element was followed by an HTML comment like:

<div>…</div><!– This is an html comment–>

From the point of view of Angular I indeed had sinned. Removing the comment fixed the issue. What to remember here is that first, don’t create sibling to your root element in your template files or strings, and second, make sure comments are within that root element or removed.

AngularJS: Unit testing that involves HTML templates

The AngularJS app I work on uses Angular-UI dialogs that load HTML templates for the different Boostrap dialogs used in the app. Dialogs are provided as a service and in my opinion while providing a nice wrapper around the dialog functionality provided by Bootstrap, violates the separation of concern between services and directives enforced by AngularJS but that’s another issue. While testing logic in my service that uses the $dialogProvider i started getting a classic Unexpected Request error while running my unit tests for the particular service:

Error: Unexpected request: GET /myapp/js/angular/app/views/partials/dialogs/request.html
No more request expected
at Error (<anonymous>)

It became clear that the issue was related to the a function in my service API trying to load the dialog’s template and failing to do so. Since I am using Yeoman as a workflow tool which includes Karma (formerly Testacular) as the testing framework, i dug around a little bit and found out that Karma provides you with an HTML preprocessing tool called Html2JS. From the AngularJS point of view, all it does it cache each HTML template using $templateCache under a key made of the path to the file.  Setting it up is pretty simple:

  • Include in your karma.conf.js file, include the path to your html files in the files config.

    files=[‘app/views/**/*.html’]

  • In the same file, add the preprocessor command

    preprocessors = {
    ‘app/views/**/*.html’: ‘html2js’

    };

  • From the Karma point of view, your setup is complete. You now need include the appropriate template in your unit test file. Declare the dependency in a beforeEach statement as in:
    beforeEach(module(‘app/views/partials/dialogs/request.html’));
  • If your application is declared in a standard way, meaning your files are served as defined in the configuration path i.e ‘app/views/**/*.html’ you are good, but in my particular case, as you can see from the error i got my actual request path is ‘/myapp/js/angular/app/views/partials/dialogs/request.html’ (a root relative URL), which from the point of view of the preprocessor and cache does not exist. I used to little trick to make it work. Here is my unit test service set up method:

    beforeEach(inject(function (_requestService_, $httpBackend,$rootScope, $templateCache) {
    requestService = _requestService_;
    rootScope=$rootScope;
    $templateCache.put(‘/myapp/js/angular/app/views/partials/dialogs/request.html’, $templateCache.get(‘app/views/partials/dialogs/request.html’))
    }));

  • As you can see I just added a new cache entry in $templateCache using the requested path as a key and the preprocessor-defined path as the key for my value since it is initially the template I am trying to load. If that’s you case you should be good to go and ready to hit the road at this point.

NB: There is a closed issue in the Html2Js preprocessor repo that allows a transformation of the cache key that would also resolve the issue I ran into but I could figure out how to set it up in my project.