early thoughts on AngularJS
¶ by Rob FrieselMy first hands-on exposure to AngularJS was when I wrote my Patented Project Management Dev Dice. It is admittedly a trivial app–hardly worth the name–but I used it to get familiar with the absolute basics of the framework. 1 But now that I’ve been using Angular for a couple weeks to build a non-trivial application, I wanted to get down some of my thoughts. Any one of these thoughts could be a long blog post in and of itself 2 but for the time being, it’s best to simply collect the following as a meditation on the subject. I trust it will be useful to someone else during the early stages of his or her first non-trivial Angular app.
Where to Begin?
Figuring out where to begin with Angular is simultaneously effortless and impossible. “Effortless” because they have some decent minimum viable snippets (MVS) 3 on their project homepage, and their tutorial at least touches on the major components and concepts, even if it is all “out of the box” stuff.
It’s also “impossible” because it’s a densely populated framework with a lot of jargon context-specific vocabulary 4 and it isn’t clear where to go for guidance around what the established idioms and patterns are for the framework’s concepts and features. Again: there is a good tutorial, but it only illustrates the simple stuff. The documentation looks like it would be extensive, but it doesn’t take long to see how thin it is. 5 If you’re willing to do the legwork, there’s some good information on the mailing list and on Stack Overflow, but the usual “archaeological” challenges apply.
Getting Started
So where does one get started learning AngularJS? Given the state of things today, this is what I would recommend:
- Read the tutorial. It’s worth reading to get a feel for how Angular expects you to assemble an app.
- Prototype a trivial app. Just write some controller code and maybe a service. Look at how routes fit together. Don’t write your own directives or filters yet.
- Read a book on Angular. I liked AngularJS (Green and Seshadri, 2013). A week or so after reading it, you won’t feel like it’s adequate, but it will unblock you on a few things. If you’re pressed for time, read chapters 1, 2, and 4, and then skip to the case studies in chapter 8 and fill in where necessary.
- Dive in. By now you should be ready to have at it.
Naturally there are some other opinions about where to start, but for what it’s worth: the above is working out splendidly for me.
A Glossary
Angular has a rich vocabulary all its own, and while it doesn’t take long to learn it, I could see how it might be bewildering to someone encountering it for the first time. If you take the time to go through the Developer Guide, you’ll see a lot of these terms defined and explained in the Concepts section. Taking a page from my own notes, this is roughly the order I encountered them, and so roughly the order in which I understood them:
- Controllers. This is the easy one. Some nit-picks about whether they’re really controllers or view-models aside, 6 these are exactly what they say on the tin. If you’re coming from something like Rails or Grails, these will make sense more/less immediately. Pro tip: try to keep your controllers “thin”.
- Scope. Or
$scope
. In the beginning, it is tempting to think of the scope as the model, but it’s not. Let me repeat: the scope is not the model. The scope is an execution context; it’s what the controller (or directive) exposes to the view layer. - Services. Angular treats these as singletons which are shared by controllers, directives, other services, and everything else. Common code goes into services. Having done a lot of work in Grails the past couple years, I found that the name means almost exactly the same thing in Angular. And/but watch out: an uninjected service may as well not exist!
- Directives. Some of the most powerful Angular voodoo, directives are ways of extending HTML. You can think of them a couple different ways; I think of them as a DSL for your app’s mark-up. They’re powerful, but the learning curve can be steep. Be prepared for a little frustration up front, but the pay-off is huge. Also: coming from Grails: “Taglibs!”
- Filters. Text transformers. They don’t do mark-up. But you can pipe from one to the next like you do on the *nix command line, and that’s pretty fantastic.
Unopinionated Models
Last year, Rebecca Murphey wrote the following about Backbone (source):
My biggest complaint about Backbone is probably how unopinionated it is about the view layer. Its focus seems to be entirely on the data layer, but the view is still where we spend the vast majority of our time.
And there’s a tentative argument to made about AngularJS and models here. There isn’t really a clear and obvious mechanism for standing up the model layer and then interacting with it. Jason Dobry wrote recently that “Angular has virtually no opinion when it comes to your Model layer.” And I’ve so far seen nothing to contradict this claim. As far as I can see, Angular just expects you to furnish objects and other values, assign them to slots in your various $scope
objects and then … serialize them? There’s some hand-waving about using ng-resource
, but so far I’m not sure I see its advantages.
As far as I can tell, the “Angular way” of dealing with your model is, as Dobry summarized it: “services own your data … controllers and directives consume your data”. 7
Animation
When you are creating a rich and dynamic web app, there is a strong temptation to give it some tasteful animation. We talk about “surprise and delight” in our applications, and judicious animations and transitions can go a long way in making an application feel smooth and polished. (i.e., Does a notification just appear? Or does it float in from the side?) Although newer versions of Angular have support for the ng-animate
directive (see “Animation in AngularJS” at the Year of Moo blog), the so-called stable version of Angular (1.0.7 at the time of this writing) does not have anything built in to handle this.
What options are left to you? Well, there are CSS3 transitions–but in my experience that won’t cover all the animations you want to do. So then you’re using jQuery or some other bit of JavaScript to do your own animations. This doesn’t necessarily make you any worse off than you were in your pre-Angular days, but you might find yourself implementing your own flavor of animated ng-show
. (Probably not ideal, eh?)
Dependency Injection and Other Magic
Did I mention that AngularJS has a lot of “magical” seeming parts? Nowhere is this more evident than in its notion of “dependency injection”.
The best description of this “magic” so far has come from Alex Rothenberg in his post “The ‘Magic’ behind AngularJS Dependency Injection”. tl;dr: Rothenberg goes into excruciating detail about how AngularJS uses some Function.toString
voodoo to look at your functions’ signatures during its bootstrap phase to figure out which services it needs to instantiate, and how this breaks when you minify unless you’re using AngularJS modules and the appropriate $injector
syntax.
Anyway: it’s a fantastic read–just to see how they did it–even if you’re not particularly interested in Angular. (Go and check it out–I’ll still be here when you get back.)
So why bring up dependency injection? Because it’s “idiomatic Angular” and you’ll be seeing it (i.e., writing it) a lot. If you’re familiar with RequireJS, it’s going to seem (superficially) familiar. There’s something very clean about providing your services this way–as arguments to the “constructor” function of your controller or directive or whatever. But it takes a little getting used to and you may find yourself wondering, as Jaco Pretorius does:
I must confess I’m not 100% sure why we need Dependency Injection in Angular.
Which, the way I read that was: If we have a module system then why be so explicit about what a given component in the module needs to know about the rest of the module? shouldn’t it just know about the rest of the module? (The comparison in my mind was to Java’s package scope.)
Again: why bring this up at all? The dependency injection seems to be emblematic of AngularJS: equal parts “being really explicit” and “being really magical”. There are a few other examples of this sort of thing (e.g., how scopes work with directives; e.g., how services don’t “exist” unless dependency-injected into some other component) littered throughout the framework. Each one has its own “zen moment” where it clicks, but there can also be a lot of bloody-knuckled frustration along the way to that enlightenment.
Wrapping Up
This post really just scratches the surface of the things I could write about with respect to AngularJS. I’ve been keeping a Markdown file of topics as I’ve encountered them, and each one feels like the seed for a much broader discussion. 8 There are AngularJS conventions, 9 Angular’s promises implementation, dealing with $apply
and $watch
, compiling vs. linking in directives, routes and $location
, the notion of providers, “jqlite” and angular.element
, integrating with other JavaScript libraries, and then there’s this idea of trying to jot down some distillation of the AngularJS philosophy as I understand it. (To say nothing of testing, which I shamefully admit to barely scratching the surface of that whole topic…)
Angular is a big topic. And though it may seem a bit daunting up front, it’s also very rewarding to bite off small pieces of it at a time and start to fit it all together. It’s an exciting framework/library/toolkit/whatever that has a huge potential and I can’t wait to see where it goes next.
References
- The AngularJS website: http://angularjs.org/
- AngularJS by Brad Green and Shyam Seshadri (O’Reilly, 2013): http://shop.oreilly.com/product/0636920028055.do
- “How to master AngularJS? [closed]”, a thread on Stack Overflow: http://stackoverflow.com/questions/14333857/how-to-master-angularjs
- “Thoughts on a (Very) Small Project With Backbone and Backbone Boilerplate” by Rebecca Murphey: http://rmurphey.com/blog/2012/03/11/thoughts-on-a-very-small-project-with-backbone-and-backbone-boilerplate/
- “Building Large Apps with AngularJS” by Jason Dobry: http://pseudobry.com/building-large-apps-with-angularjs.html
- “Animation in AngularJS” at the Year of Moo blog: http://www.yearofmoo.com/2013/04/animation-in-angularjs.html
- “The ‘Magic’ behind AngularJS Dependency Injection” by Alex Rothenberg: http://www.alexrothenberg.com/2013/02/11/the-magic-behind-angularjs-dependency-injection.html
- “AngularJS Best Practices” by Jaco Pretorius: http://www.jacopretorius.net/2013/07/angularjs-best-practices.html
- Framework? Library? Toolkit?[↩]
- I feel like I’ve got an “Angular book” bubbling up from somewhere deep inside me. And I’m still not sure if that’s where it should stay…[↩]
- Which, say what you will about the MVS, I agree with Fogus that it can be a very effective way to market what your library is “for” and how it is differentiated from competitors.[↩]
- Directives? Transclusions? Injectables?[↩]
- This complaint about the documentation is one that appears in a lot of blog posts about Angular.[↩]
- ”Model-View-WHATEVER![↩]
- That being said: I feel like I came across a Stack Overflow thread where someone was more/less asserting the opposite about services–that a service should not exist for the purpose of dealing with your model. Alas! I have not been able to re-trace my steps, and so it will remain apocryphal and relegated to this footnote.[↩]
- ”Broader discussion” = long-ish blog post.[↩]
- …or lack thereof? Both Dobry and Pretorius make references to this loose approach to application structure.[↩]
Leave a Reply