Hacker News new | comments | show | ask | jobs | submit login
Using AngularJS at Localytics (localytics.com)
152 points by abuggia on Apr 10, 2013 | hide | past | web | favorite | 56 comments

For those commenting on the poor quality of Angular's documentation (a complaint I share), check out John Lindquist's videos at http://egghead.io/ . They're not comprehensive, but John spends a great deal of time explaining the nuances of directives, especially isolate scopes and transclusion and his explanations are clear and intuitive. Prior to finding John's videos, I watched all of the "official" Angular videos which I found more often frustrating than illuminating, but John set me straight. Can't recommend enough.

And if you're struggling to ramp up on Angular, I would recommend sticking it out. The learning curve is steep (or is that gradual?--I never understood this analogy), but once it clicks, your productivity will go through the roof. Angular has redefined what I mean when I say "rapid prototyping."

I couldn't get your link to work, but it appears that his egghead.io videos are on his youtube channel.


Mike, thanks for the link. I just asked about egghead being down.

I second this. The videos are really great and are delivered in a way (short, to the point) that really helped me connect the dots in the areas where the Angular documentation wasn't sufficient. Especially the directive api, John does a great job there explaining isolate scope which was confusing to me for a while. Once you get it down you begin to realize how powerful Angular is.

100% agree. Single best angular resource on the web. Especially w/r/t his isolate scope explanations.

I agree. I've been going through his tutorials and they are great. Fire up sublime with node.js running as a simple http server and you can quickly follow along building simple apps that will get you up to speed.

it is http://egghead.io alive ? It seems down at the moment.

See above, John is working on a re-design: https://twitter.com/eggheadio/status/322062696583413761

Anyone thinking they made a mistake using Backbone, please read this: I've been using backbone for about 1 month, refactoring a huge jQuery spaghetti project, and I have few observations:

1) If you have a new project, I would go with Angular (or even Ember if you are from a Rails stack)

2) If you want to refactor an existing one, check Backbone, it might be a bit less causing a rewrite rather than a refactor

My tips if you still choose backbone:

- learn it first inside and out, spend at least 2 days doing any tutorial out there, even if it's a few dollars (code school, peepcode, tutsplus etc)

- make sure you learn 1.0, older examples might be confusing

- read the backbonejs.org documentation from start to end, and read the annotated source, especially read the FAQs and also read the github issues, jashkenas (the author) is sometimes responding himself

- I tried to avoid any plugins at first (no Marionette, deep model, BB-relational etc) if you see you need too many plugins, just ask youself if it's worth it, you might want to give Angular (or even Ember) a chance. I found out that for anything that looks hard, there is a way to do it in Backbone the "backbone way"

- Last: remember that Backbone is simply helping you get code from the form of document on load God function with tons of event listeners, that trigger ajax calls, that trigger dom manipulation, to about the same code, but in models and views, so you can make sense of all of it, that's all.

Yes, you need to clean up your listeners, and when using the 1.0 listenTo and stopListening (which are automatically called when you remove a view or destroy a model) then you are going to be ok with the zombies.

Backbone taught me a lot of JavaScript, it was more perhaps harder than Angular but the code is readable to anyone without even learning backbone, it just makes sense

so don't expect Backbone to do any magic, it doesn't, but it is still a very relevant and valuable utility library, and I think it's a must have step in any front end developer's life to do at least one BB app before moving to Ember or Angular (just my humble opinion)

Backbone has taught me a lot too, I like that it doesn't do any magic. Angular is pretty amazing though at how simple it is to do things with, I'm a bit worried about the magic part. What happens when things start growing and the magic breaks, do you have to read the code base to figure out where it went south? I started playing around with ember too. It's a bit tricky, I found I had to compile it to get it to work, the starter kit wasn't cutting the mustard for me.

We used to write things like

    <a href=”#” onclick=”doSomething()”>
Then we realized it was bad to couple presentation and behavior, so we made our Javascript unobtrusive, keeping our templates clean. But now we’re back at it again, writing

    <a href=”” ng-click=”doSomething()”>. 
Have we learned nothing?


This seems like a good point that I can't refute - anyone?

Honestly, there's not a huge amount of difference between

  <a href="#" id="show-help-link">Show Help</a>
  <script src="text/javascript">
    $("#show-help-link").click(function() { showHelp(); } );

  <a href="#" ng-click="showHelp()">Show Help</a>
I mean, HTML has behavior in it. A link in itself is "behavior": when you click this tag, go to the page defined in the src attribute. So, as the author says, it's not really a bad thing that templates have behavior in them. In Ember.js, for example, you have an {{action}} handler that is essentially the same as ng-click - "run a function on the controller when this is clicked."

I think it's because needs evolved. When we went away from tables to use stylesheets, the goal was to keep the same html but alter the presentation with css and js (for the animations). But now, it's not just about presentation anymore. Real applications are built and maybe it doesn't make sense to keep the html and throwing away css/javascript on a full-rewrite. Basically, the html we code right now is way more tied to the javascript that it once was. So, having them in two separate files doesn't make that much sense.

Oh, and, you can use $('#show-help-link').click(showHelp); instead of click(function() { showHelp(); }); ! : )

You don't need the src="text/javascript". Only <script> ... </script> is required.

Heh, I meant to specify "type" and not "src", but you're right regardless.

This is a choice you can make in angular - you can do it the other way if you want. It's totally up to you.

We're building webapps - there's going to be behaviour attached to dom nodes. You could use a class instead but in my experience you end up in a worse place. When people do it as classes (or data attributes / whatever else) someone is going to come along and wire styles to those. You'll just end up with a much more twisted coupling of behaviour and presentation. I've unpicked this mess more times than I care to think about right now.

Also, it's really different in Angular - the behaviour is not as coupled. Each element has its own scope - the old "bad" way was wiring up html elements to GLOBAL scope. That's obviously not great.

Edit: so I don't sound so snarky.

The first one requires a global method. The angular one is a method that is tightly scoped and easy to test.

This too

There is an immense amount of guilt and shame concerning the subject of markup and JavaScript living together. It may help if you rationalize it this way.

The second one not HTML at all, rather it is written in an XML-like configuration language which declaratively specifies the structure of the view, in which the attributes use Angular's JavaScript-like expression DSL to declaratively specify how its elements are bound to the behaviors available on whatever controller has been injected into this template. This allows you (or a non-coding designer) to completely change up the connections, appearance or structure of the view while touching no JavaScript whatsoever.

So in this case the markup and the behavior can be intimate, without actually coupling; thus there is no need for anxiety.

Connecting presentation and behavior has to be done somewhere, otherwise your presentation do nothing and your behavior can't display. You shouldn't confuse "couple" with "connect".

Having a "onClickButtonA()" function call bound to a button whose id is "A", and then have the logic associated to the click on that button somewhere in the controller is a completely different thing than having "checkAccountBalanceAndSubmit()" directly in the HTML.

Angular remove 80% of explicit HTML/javascript conversation that were only there to dumbly synchronize input views and model. The rest is just really unavoidable.

The alternative is a slew of loosely-coupled and opaque attributes (IDs and classes), especially where you're not sure if a particular class or ID is used for presentation (CSS) or functionality (JS). How do you handle refactoring when you use some classes for JS and some for CSS?

With custom attributes there is no confusion, and although it goes completely against the separation of concerns and now your mark-up isn't completely declarative -- it's a necessary drawback.

What about some kind of Hungarian notation for classes?

pBlue bWidget?

I've never done this, just wondering.

if you have functionality class/ID, do you really have separate concerns or do you just have moderate/loosely coupled concerns?

Well the most disturbing thing about this syntax is for sure the use of parentheses. Drop them and you will get old good ng-click="doSomething" which doesn't differ at all from class="ng-doSomething" or data-ng-click="doSomething".

But parentheses try to lookalike the onevent attributes, which a) everybody doesn't like and b) immediately invoke javascript code

In AngularJS point b) can't be the truth - there is for sure some layer of expression evaluation, and that is what disturbing - as an experienced javascript developer you know that this layer exists, but you can't easily see what happens inside that layer - AngularJS hides that from you.

In most cases in traditional JS development - nothing really happens in this layer, it's just a dumb method invocation in the context of the view and has dom event as a single argument - this is clearly visible in libs such as Backbone.

But in Angular this layer of expression parsing and evaluation does exist - and you don't know what kind of magic happens there and how thick, maintainable and overridable this layer is. This possibility of dirty magic - that really disturbs me in all the simple tutorials of AngularJS, so I don't have courage yet to give it a try in a serious project.

My best attempt:

HTML already has a bunch of behaviors embedded in it. Links, styles, dropdown menus, input fields, radio boxes, etc. The angular devs are simply embracing the declarative nature of HTML and extending its available behaviors. In that respect, angular is actually treating HTML more like it was intended to be treated.

And I agree with the OP's lamentations about the javascript being completely divorced from the HTML. You end up with code that is so decoupled it's a major undertaking for someone new to your project to figure out what's going on. In an angular.js app, all they need do is look at the HTML and they can get a good idea what's supposed to be happening and where.

edit: And the truth is, jQuery apps aren't polluting the HTML any more than Angular apps, they're just doing it in the form of additional CSS classes and IDs and "data" attributes. In that respect, you could say that jQuery pollutes the css declarations.

data attributes are baked in to the html5 standard

This is my #1 complaint about angular - I keep hearing good things about it and going to try it, then I see markup like this and can't get myself to

Strongly suggest looking beyond this if your concern about Angular is that it is returning us to an old approach. Angular, on the contrary, in my experience, is a broadly conceived vision of how to rethink and move browser development significantly forward. I have been waiting for something like this. The key part of that ng-click is that it's an Angular 'directive'. I recommend adding AngularJs to your app to do a simple experiment of writing a few directives of your own; see if that doesn't light a bulb.

What solution are you comparing it to?

    <a id="clickable-link">
And the putting something like the following into a js file:

I find the declarative markup of a well-written angular app to be quite clean and easy to read, much more so than the alternatives.

The article did go on to say that there's no perfect place to put it but it still has to live somewhere. To expand on that, an event listener, by definition, is going to contain some DOM and some business logic. So no matter where you put your listener half of it will be out of place and reliant on some other code (attribute/function names) that may change in the future. Placing listeners in the DOM is the lesser of two evils simply because it is easier to write backwards compatible business logic/javascript than HTML.

The difference is onclick="doSomething()" runs doSomething() in the global scope. Not good!

ng-click="doSomething()" runs doSomething() in the scope of the controller that contains the element. Good!

Separating content from presentation matters.

For documents.

Applications are not documents.

My angular story:

My team was at a similar crossroads a few months back when trying to decide which javascript framework to pick for our mobile app. It came down to Backbone, Angular, and CanJS (because we had previously used JavascriptMVC on a project). It really came down to Backbone vs. Angular and we were leaning heavily towards Backbone. We all built demos using each of the three frameworks.

I was the Angular advocate and after having experienced incredible joy creating my demo I was desperate to get the rest of the team on board. After much debate we were leaning towards backbone, until that is, I asked "how would you go about making sure your views are updated and your forms validated". After we walked through the work that would be needed to be done maintaining the view state in real-time on a backbone app, and a few other examples like retrieval of form data or validation of forms, it became clear we'd need to write a lot more DOM manipulation glue-code using Backbone than we would with Angular.

In the end, this was what pushed us over to the Angular side. The focus on testing and the dependency injection throughout was another huge selling point for us. And frankly, it wasn't clear to us how a Backbone app should be structured. In fact, that variability appeared to be one of the main selling points of the framework but it ended up paralyzing us with choice. Being first time Backbone developers we weren't sure we could ever feel confident knowing we were following best practices.

My experience with Angular.js was not that good though. May be I am real dumb, I can't see anyone with similar experience. I was totally frustrated with the amount of things I had to handle to bind my backend API. And also there were several issues like $scope.variables going wild. In short, it was a total mess in my case. I rather decided to roll out with Jquery instead. The code got totally cluttered I accept, but Angular.js frustrated to the point that 'elegant code' was least of my concerns, I just wanted to finish it somehow and run away and never look back.

Were you mixing dom manipulation into your controllers? That can make things go haywire because they happen outside the standard compile and link phase. Sometimes it works and sometimes it doesn't. Using the directives (which I admit are super confusing at first) can alleviate this issue because they are executed in the normal Angular update cycle so everything happens in the correct order.

I decided to use AngularJS on a side project of mine, after considering Backbone and EmberJS. I am not a JS expert, but I am pretty sure AngularJS will be an industry standard in a few years.

I think as mobile becomes more dominant angular will have to find a way to work tighter with the closure compiler in advanced mode (or something akin) to remain relevant.


I'm not sure why the OP links advance compiling specifically to mobile. It's good to have smaller, faster code on any platform that isn't quad Xeon with a fiber connection.

The Closure ecosystem has their own templates (soy) which are compiled in Advance Mode (with renaming) by the Closure Compiler. It's not possible to do that with Angular attribute's which reference JS names.

See this conversation about Angular support in Closure: https://groups.google.com/forum/#!msg/angular/hePiqQA-MCI/uT...

you touched on several of the problems i forsee. angular parses templates client side, which is expensive IMO, smaller better optimised code with proper dead code elimination leads to a faster experience. as for mobile, i use it as the final use case, where the bad decisions which you make get amplified the most.

Stickit author, here. To be clear, stickit will not make your "zombie views grow fatter" or contribute to any memory problems. In fact, stickit cleans up all of its model and view bindings automatically on view.remove(), and provides an optional api for manual cleaning view.unstickit().

The blog author's problem was a brief bug that was introduced and fixed between releases for the rare use case when a data-bound view is re-rendered. We fixed this problem and the author confirmed that the patch was "working great."


So even though the problem was fixed for the blog author before he moved onto angular, he still claims that stickit causes memory problems. I guess a false claim like that makes the story of moving to a new framework more entertaining.

Another claim from the blog author is that stickit makes it hard to use third-party plugins like Chosen. Around the same time he filed the github issue, we were finishing and getting ready to release "handlers" and a new "initialize" binding which give you the ability to create global handlers for setting these kinds of bindings up. More on handlers here:


... and an example of setting up a global handler for Chosen:


I've been using AngularJS for a few months on a side project of mine and it greatly helped move a lot of the code complexity to the client side. Hooking it up with a REST API was simple and got rid of almost all of the server side rendering.

Here's a particularly useful sample app, implemented in both Angular as well as Backbone.


This post is is so popular, my fork from half a year ago (very few additions), still gets starred approx. once a week.

> Working with isolate scope and transclusion is tough, and Angular’s documentation on the subject doesn’t make it easier. We found that before jumping into writing an ambitious directive, it’s best to start by not writing a directive — just using normal templates and controllers — and then roll that code into a directive once you really figure out what your requirements are, or once you start repeating yourself..

Directives are, IMO, the most powerful parts of angular. They're also the most confusing. OP makes a great suggestion here that I'd recommend as well: Start with a normal template & controller then refactor into a directive later. In my experience, I've found that it's been useful to focus less on the DOM manipulation that needs to take place and more on the where the data collected needs to flow. In this way the directive just becomes the "glue" between a tiny area of the DOM and a parent controller and/or scope.

I guess you could liken them to the behavior/logic you'd have in a backbone view? That may be a stretch though. Powerful nonetheless.

We've had a similar experience at https://starthq.com. One thing we noticed when writing directives is that it's often faster and easier to implement them from scratch rather than wrapping a jQuery plugin. Also, we've pushed a couple of fixes upstream and had them appear in a stable release within a few weeks due to the quick release cycle.

Love AngularJS. My grips so far :

- Directives : I'm no JS ninja so even after those egghead.io I'm still lost, but it gets better !

- jQuery : Angular kinda want to kill it whereas I think it should play nicer with it, especially for plugins. AngularUI jQuery Passthrough (or custom directives) should not be necessary IMO.

- Expressions : they are powerful but there is almost no documentation about them and I feel like an idiot sometimes. Thank god for Stack Overflow ... (where in the Angular doc can I learn that I can do ng-click="[action_1, action_n]" ?).

- Views helpers are usually put in the controller. That doesn't seem the best approach, or maybe people put them in a service and inject it in the scope from the controller ?

- Providing initial data : I usually put data in javascript variables and get them in the controller and assign them to services or the scope. Is there a better way ?

"Directives are hard. Working with isolate scope and transclusion is tough, and Angular’s documentation on the subject doesn’t make it easier. We found that before jumping into writing an ambitious directive, it’s best to start by not writing a directive — just using normal templates and controllers"

I have the same experience. I also tend to do the occasional DOM manipulation from the controller, using jQuery. I know it's frowned upon in the Angular community, but it at least allows me to experiment and, as the quote implies, figure out what I want before I know exactly what I need.

That being said, I'm starting to use directives more and more, and they are certainly a powerful tool that cannot be ignored if you are going to build an Angular app.

Our team in finishing a project to refactor a custom form builder in our app (similar to WuFoo) and our struggles sound very similar. We are adding plugins like Backbone Relational to fight with issues, and fighting issues with the plugins... And in fact, our tech lead has actually forked Backbone (still unsure as to the exact reason). At any rate, we have shattered (what used to be) a ~1,000 line jQuery/JavaScript file into nearly 130 individual fragments of models, views, collections, templates, and helpers. Throw RequireJS into the mix... We can't be Doing It Right (TM), can we? Or are we, and I just don't get it?

[edit] spelling

Good write up! I've been on the look out for examples of larger migrations from Backbone to Angular. I'm about to tackle one myself, but wanted to make sure it was the right decision before diving in.

Nice, thorough write-up. For people considering Backbone, though, I will say that I've written several non-trivial Backbone apps, and negotiating the form view re-rendering problem is not that difficult and certainly does not require an extra data binding library. Also I've had no problem integrating the Chose plugin into Backbone apps.

Dealing with deeply nested views can still be a bit of a headache, but I prefer the extra control over view rendering that I get with Backbone vs. soem other frameworks (I have no experience with Angular).

I have been working in the past few months with angular and have nothing but good things to say other than complaints about the docs and the complexity of directives/transclusion. He doesn't mention it but the coolest thing for me so far is the transparent use of promises in the templates. The unit testing support with testacular/karma is good as well, but I'm not sold on the e2e testing with angular-mocks, would like to hear more on this subject.

Is it just me or is Backbone just not that hard? I don't quite understand their data binding situation. You should not need to look at the DOM for elements with specific IDs, unless you have truly singular views at the top level.

I get the feeling that their form re-rendering headaches had to do with parent views that were listening to unnecessary events, like a collection view that listens to individual model events.

We've got a very large app built on Angular, and it has been a real pleasure to work with. The directives are the killer feature for me. There are some definite esoteric bits that can be puzzling at first, but after you crest the hump it is rad. I love it.

I'm a fan of Knockout.js. Has anyone used both and can comment on their merits?

Angular is just so sweet

i dont know, built this with angular : http://markme.alwaysdata.net

it works , i like the DI stuff though i always used my little lib for that before( https://github.com/Mparaiso/Pimple.js ) .the 'dirty checking' always felt like a hack , i'm glad Google is working on it with Object.observe. as for the code inside the html, since it is a "scoped" eval with its own dsl it's fine.

But i still use backbone especially for games and non dom related apps.

what matters is choice , and angular is still light weight compared to beasts like Sencha.

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact