Hacker News new | past | comments | ask | show | jobs | submit login
Lessons Learned: A Year with a Large AngularJS Project (joelhooks.com)
277 points by joelhooks on May 23, 2013 | hide | past | favorite | 132 comments

I think people who've worked a lot on 'classic' web pages misunderstand some things. Angular and other MV* frameworks are not out to replace or add on to JQuery or Underscore or any other JS toolkits. They are out to replace Rails and ASP.Net and Zend. Or at least large parts of what those apps used to handle.

You will still use all your JS tools, it is your server tools that will get lighter-weight as page flow and layout are (exclusively sometimes) moved to the client. Ideally your server logic returns only JSON and otherwise your server is a file host for HTML, JS, CSS.

Edit: my comment is in response to some other comments I've seen, not the OP.

This may be the case for pure single page apps, but any real world application will have some pages you want to load faster and have easily indexed by search engines.

At https://starthq.com we started out as a single page app with a RESTful API using Angular, but with time it has become apparent that there are certain public pages that need to have the HTML generated server side. Now we have a hybrid solution, where some parts of the page are generated on the server and others, namely the parts that are different for anonymous and logged in users, on the client.

We've experimented with the likes of https://github.com/apiengine/seoserver but the truth of the matter is it's actually easier to generate the HTML server side than using Angular.

I agree that's an issue, and I also agree your workaround is the only one right now. That said, I view the architecture of having the client machine do view logic as being more sound, and I view the issue to which you refer as an SEO issue (rather than a fundamental problem) that the industry needs to come to grips with. Since AngularJS is from Google, I have a feeling they agree and we will be moving in that direction.

Yikes, Angular can't generate semantic HTML at the server yet? That explains why http://docs.angularjs.org/misc/faq is such a trainwreck. Letting crap like

  <a href="{{page.url}}">{{page.shortName}}</a>
go out on the wire to be uselessly displayed by arbitrary clients (even ordinary browsers that don't blindly trust your scripts) is a really severe failure mode.

Um, Angular runs on the client. "Generating semantic HTML at the server" isn't Angular's job.


I completely agree with this. I am working on a web application at the moment, and the server is very minimal. It just handles supplies a JSON-returning REST API, the index page, and some WebSockets stuff.

Doing things this way is quite nice, and forces separation between the client application and the server application. It makes the web application just a client, on an equal footing with any other client (iOS app, Android app, desktop application etc).

what are you using for the REST API on the "server side" ?

yes! this is exactly what I'm doing with Angular. I'm working with django on the server and have been able to thin out my server dramatically. It is now providing a RESTful api and doing some minimal business logic but I have been able to shrink my server side template rendering down to nearly nothing (just the bootstrap template served to the landing page). Angular is handling ALOT of display logic and user interaction logic that previously was handled server side.

are you using tastypie, the django rest api, or just writing views from scratch? what do you think is proper level of integration between a rest api module for django (or more generally a server-side library) and a client-side model layer such as anglar's or backbone's? and where do you place those boundaries, particularly when your rest api might be used by more than one type of client?

in any case, yeah, one way or another, serve static files & expose a rest api. this is the way forward. i'm excited too, just not exclamation point excited. or, well... fine: !

Most angular diehards really try to use as little jQuery as possible, since most the times it's not needed to do what you want to do

I guess I'd say most of us try to encapsulate it in directives or use the scopes that are there for us, but even Angular uses JQuery or its own jqLite under the hood.

edit to add: In fact, on further reflection, Angular passes JQuery or JQLite objects to the Link functions of custom directives, so it's actually kind of opinionated in favor of using JQuery, it just adds some extra layers of abstraction to ease some things.

Angular's jQLite does the job just fine. If you're writing directives, and not putting all your DOM manipulation in the controller, then jQuery is no longer necessary / useful IMHO. Why pull it in at all? The only thing it lacks is DOM wide selectors, but again, if you're writing a directive, you're passed the element, and you can do selectors on that element and it's children, which is all you should need -- otherwise, it seems the abstraction has started to leak, and requires re-consideration for your design.

I don't use any jQuery transitions / animations. Angular's own $http service does all the Ajax I need. YMMV, but I like the fact that I can avoid library bloat by learning one useful toolkit very well, and applying it effectively...and I happen to like all of its other features.

The display side of traditional frameworks might not be needed but there is a lot functionality they still supply in the (backend) Model and Controller side of things.

Just finished building a personal angular web app (http://pokerstoker.com). Generally a pleasant experience! I found the incompatibilities with other libraries (e.g. jQuery) a bit frustrating though.

I used to have a problem, so I thought to use AngularJS. Now I have a ProblemDirectiveFactory. http://stackoverflow.com/a/15253892/521834

Show me any code that cannot be written faster and shorter using only jQuery, Underscore templates and a CommonJS compiler. Does not exist. You are writing enormous amounts of glue code to please AngularJS and getting lost in your obsession with tools, imagined reusability and over-complicated testing procedures.

You are completely missing the point of directives. Your proposed alternative strategy of using "only jQuery, Underscore templates and a CommonJS compiler" will leave you with DOM manipulation code entangled with your controller logic and a nearly untestable mess. Directives are meant to encapsulate any code that directly deals with manipulating the DOM so that stuff doesn't leak into your model or controller logic.

You of course don't have to throw everything into directives but then you risk making your code less portable and your tests more brittle. Wrapping a jQuery plugin in a directive is so trivial it's not even worth mentioning, and it certainly doesn't result in "enormous amounts of glue code to please AngularJS".

> over-complicated testing procedures

And this is where you showed your hand. You can't have written tests for an angular app because if you had you wouldn't have made such a bizarre statement. Angular's dependency injection combined with the fantastic Karma test runner makes testing an absolute breeze.

Sorry but I personally find testing in Angular very fuzzy. It works great on school examples (test a function that should reverse a string) but in real-world I never know how to apply it or even what good it will do.

Where do I start and why is it better because of DI? Also Karma still requires something like Jasmine which means I need to learn two new tools (as well as how testing works in Angular). It is complicated for someone who is not used to testing at all.

> so trivial it's not even worth mentioning

If it is so trivial then it 'is' worth mentioning. Give an example or reference. Personally I like Angular, but I'm learning and finding articles like the OP's are great to read to have others' perspectives on how to work with it.

I mean it's not worth mentioning in a disparaging way.

Paste a directive here that shows how AngularJS is not bloated.

Sometimes it is smarter for the short and long term just to right a little jQuery in your controller. You are right, don't worry about reusability until you actually reuse something for the 3rd time.

If you are going to be doing something a lot (capitalizing the first letter in your example), then I think writing the filter does save you in the long run. Writing the filter doesn't seem worth it when you project is small. When you project gets big, and there are little one off jQuery statements everywhere, it gets unmanageable.

The filter allows you to look at your template and immediately know why that word is being capitalized. With jQuery, a year from now you won't remember why/how it is being capitalized, and you'll be grepping for ids and class names.

Having worked on a sizable AngularJS project for a good while, now, I can't begin to imagine where you're coming from. The strength of Angular, in my opinion, is that I write ~1/10th the code I'd write using jQuery & Underscore. Event handling, display logic, data binding, directives, resource factories – all of these and more mean I can focus on my business logic as opposed to re-binding events when I update the DOM and the dozens of other trivial bits I have to care about when using jQuery (or Backbone, really).

Obviously jQuery/Backbone setups have their place, but to claim that AngularJS makes you less effective is absurd.

I've used both Angular and Backbone pretty extensively and I think client side MVC in general makes you less productive. I've been starting to use PJAX with a splash of jQuery for most pages. Only using Backbone / Angular for pages that really require it. Have seen a big productivity boost and apps are as responsive. Too many people are seeing client side mvc as solution to everything. I did at first as well.

Then you are bad at programming. 1/10th? Code or it didn't happen.

And when you will leave your enterprise, your code won't be maintainable anymore because the next developers will have no idea about the architecture of your application. Then someday someone will say "well ... nobody understand this code anymore ... let's get ride it, guys. I guess it's time for feature freeze.".

Of course, we're talking about some size of application here. If you just want to make a todo list, jQuery is fine. But when dealing with a potentially huge codebase, it is good to enforce practices.

> Show me any code

Here's an example from Miško Hevery's session on Angular.js at Google I/O:


He displayed the equivalent jQuery code side-by-side and the difference was dramatic (spoiler: jQuery was more code).

Do you have the jQuery code he write for comparison? I assume he re-wrote or copy-pasted a lot of code any experienced developer/team has long ago extracted into small, reusable libraries, such as history management or short-hand ajax requests.

That wouldn't make the comparison invalid - if he's not using anything not supplied by AngularJS, then a comparison to JQuery would also not use anything not supplied by the package.

You fail to present any case in which AngularJS improves development, maintainability, reusability or testability. AngularJS, much like Ember, Spine, Backbone, TinyMVC, Meteor, ... is good at one thing: Making that Todo demo.

Angular helps you organize and test your code. How did you test your 50+ onclick functions? Did someone come after you to do maintenance and agree the jQuery was the way to go?

I wouldn't test 50+ onclick functions. I'd used event delegation to assign the click handler to the appropriate parent element. I'm not experienced with Angular, but the last time I checked it didn't support event delegation :(

Are you saying you are writing tests for all of your 50+ ng-click functions then? What's the difference?

jQuery 1.9.1 + Underscore 1.4.4, minified and gzipped is 37,283 bytes. Angular.js 1.0.7 minified and gzipped is 30,254 bytes. So you're actually sending down significantly less code for small projects if you're just using angular.

Furthermore, my experience has been the opposite of yours - I find myself writing far less glue/boilerplate code with angular.

I'd be curious to see any large Angularjs apps. Do you know any? How big should single page apps be allowed to be? Is there a clear use case for this to be sensible? This is not a loaded question in case you or someone mistakes it for such...

I would not call it a big app but 5by.com is written in some 2.2KLOC of angular and I feel like it shows some of the strength of the framework.

Code or it didn't happen

It's clear that you're here to troll or to push an agenda, and not to learn. I personally do not care what technology you use. It's not my responsibility to convince you that your current practices are suboptimal. I'm not a contributor or in any other way affiliated with Angular, I just think it's a really well done framework.

I've downvoted a couple of your comments in this thread that were in a similar style. HN isn't reddit.

Please educate yourself on the way discussions are conducted here.

Strong assumptions!

dear bloggers and commenters, you really need to qualify "large". "Large" probably means something between 10k LOC and 1M LOC and the approach to coding at either end if this spectrum is vastly different.

For example, I'm at the 50k mark on the frontend and I found angular's basic building blocks to be too restrictive in terms of organizing things into reusable components. I had to answer questions like "can views do I/O", "does a view own his model", "how deeply should views nest", "should my models be tree-like or rectangular", "can my contracted designer write arbitrary markup with arbitrary UI widgets or does the framework not like that". Angular's way of doing controllers with dependency injection got in my way of answering these questions. I would love to read someone's opinions on this, especially if I'm wrong, but nobody (including me) has time to write a well thought out essay on this.

I agree. I think when people say "large" they mean that spaghetti jQuery code wasn't working anymore. I was able to get to 10K LOC with a well thought out hombrew jQuery framework (Angular, Backbone, etc weren't available when we started), and it was still fairly maintainable. As I approach 20K lines of code it is getting out of hand. I would like to switch the project o Angular.

I'd love to hear more about the problems/questions you are having. Have you found answers to some? Here's what I have come up with. How does it compare to what you are doing?

"can views do I/O" I've put file I/O in a controller. If I would have needed to share it across multiple pages, then I would have put it in a service

"does a view own his model" I have model classes defined outside of Angular. Services access my API to create new objects (of types defined by my models). Controllers request data from the services. The service figures out if it already has the data or if it needs to call the API.

"how deeply should views nest" I often wonder how much I should be breaking up my views into smaller view. For the moment, I only create "subviews" if I am going to reuse the subview in another view. This has lead to some large template files. I may need to reconsider if they get much bigger.

"should my models be tree-like or rectangular" I don't understand what you are asking. What's the difference?

"can my contracted designer write arbitrary markup with arbitrary UI widgets or does the framework not like that" Again, I'm not sure what you are getting at. Arbitrary markup and UI widgets as apposed to what?

i do believe i have answers to all those questions; its really something that i need to write an essay about, a short blog post or HN comment can't do it justice. If enough people upvote this or ask me on twitter, maybe I will write something up this week.

You should really do this. The Angular docs are OK, but don't make any discussion about these larger questions. There some scattered posts on the mailing lit about different approaches, but that's it.

to me, 'large' in th context of evaluating whether your project would benefit from a more heavyweight framework like ember or angular means 'lots of objects on the page'. I've got a web app in backbone that doesn't do any tricky js, isnt too many LOC (yet!) but now I'm wishing I'd used ember because of the number of full feature objects I'm representing on each page.

I haven't actually taken the time to get the metrics, but probably in the neighborhood of 50k.

Try sloccount or cloc:



Both are in all the major repos -- apt, yum, ports, brew etc.

I have a hard time adopting frameworks because of the all-or-nothing aspect of them. If you use Angular, you have to use their templating language, right? I know that they do a lot of powerful things with it, but honestly it's difficult for me to throw away all of my current tools. It's just too much of a jump.

There's so much I love about libraries like angular and ember, but I'd love it if someone was working on a way to allow additional templating languages. I don't know how it would work, but you could possible compile other templates down to angular templates.

I've been thinking of a way to convert simple templates in angular's style, so that you can do all the cool auto-updating features. If there was a standard for this, templates like mustache, etc could compile a subset down to it.

Disclaimer: I'm the creator of nunjucks https://github.com/jlongster/nunjucks.

The way most developers work with JavaScript (especially jQuery) is fundamentally broken and untestable. This was one of the most difficult things I fought with when using backbone and introducing developers to backbone. You can work with it the way that you know, but that is the hard way. It will make team scaling more difficult than it needs to be and you will be missing out on what the majority of the framework does for you.

This is a major reason why I am coming around to Angular. Take away jQuery and developers have to stop and think. It makes it difficult to rush ahead chaining dozens of callbacks and tightly coupling their code to the DOM, in the familiar jQuery way. This, above all else, is what allows you to create a single page web application. The rest is just gravy on top.

It's easy to tell Angular to use different syntax for interpolation:

   myModule.config(function($interpolateProvider) {
However, you should be very cautious with mixing server-side and client-side templating. See:


That's an interesting approach, but I'm assuming this only works with variables, and you can't use loops or anything else. That might get you most of the way there though.

I can't speak from any experience with angular, so this is about all I can say. I think it's great for one-page apps, but otherwise I enjoy writing templates without thinking too much if they are rendered server-side or client-side.

I'm in the same boat as you. I like the looks of Angular, but not sure I want the client-side lock-in.

I enjoy writing templates without thinking too much if they are rendered server-side or client-side.

Funny, I've been considering this architecture:

  client :: js + your nunjucks library for templating
  server :: python + jinja2 for templating
Are nunjucks and jinja2 pretty compatible now, to the point that you're actually sharing templates across client and server? The docs currently discourage it:


I should definitely update that section. The mozilla marketplace (see fireplace[1]) actually ended up using it, and they share templates across Python and node.

It is mostly feature-compatible, but there definitely differences, and the fireplace project installs a compatibility layer. There are minor things, like `True` is `true` in nunjucks, and arrays have different methods. Also, all filters/extensions must be written both in node and Python.

You can go very far though. I'm considering adopting this compatibility layer and putting it behind a flag. It takes some work, but you can definitely do it.

[1] https://github.com/mozilla/fireplace/

Thanks for the reply, I'm actually going to give nunjucks + jinja2 a shot now.

Food for thought: jinja2.meta exposes the AST after parsing the template. Could you use this to do Angular style data binding?

What do mean exposes? Once the code is generated, the AST is gone (or so I thought). But yeah, there's some neat things we could do with massaging the AST into something more like Angular. Stop giving me ideas!

Take this:

    env = jinja2.Environment()
    ast = env.parse(...)
    vars = jinja2.meta.find_undeclared_variables(ast)
Now you've got a list of every part of the data model referenced by this template. Unfortunately this doesn't give you byte ranges for each reference, but that could be changed.

Angular propagates changes to your data model to only the parts of the DOM that depend on it, which is cool. Imagine if you could do the same against a nunjucks template. Given the above kind of dependency analysis, I don't see why not.

Maybe rendering snippets of a jinja template at runtime is problematic?

Aside: yikes on the string-based codegen here...I bet you wish you were still writing scheme ;)


Oh, yes, nunjucks features a full AST and parser like jinja2. The compiler calls `parse` and then `compiler`, so we can analyze the tree between those two stages as well. I'm thinking of hacking around on this, it is interesting!

It is for variables, but that's just because Angular has such an elegant way of iterating through loops:

   <li ng-repeat="friend in friends">
     {{friend.name}} who is {{friend.age}} years old.
It's the ng-directive, and it's just one example of why directives are so awesome and powerful:


It's not just your tools though. They are asking you to throw away many of your ideas about web development as well. They ask you to adopt a new paradigm that doesn't fit in with the template, innerHTML style of development.

If you embrace that idea, and go with the flow, you can do some amazing things amazingly fast with angular that doesn't work so well in other frameworks.

I've used Jade and Angular in the past. Angular allows you to change the bracket notation to something custom, which helps avoid conflicts.

For the type of app I've been working on, the all-or-nothing hasn't been a real hindrance, but Angular is definitely a Framework and not so much a modular toolkit (like Backbone, for instance, which I would say is generally a better choice if you want to build something "custom")

Everyone is telling you ways to get around this, but IMO, if you aren't using Angular templates, then you really aren't using Angular.

ng-repeat, and other powerful directives are what's great about Angular. Instead of writing code to loop through something, you declare that it should be repeated. Templates are much easier to read this way.

Directives change you way you view your markup. Instead of writing a script that generates the markup you want, you are using a new, more powerful markup language that knows about repeated elements (among other things).

And when the data changes, the webpage just updates, with no thought required by you. Recently, I have started using Firebase, which makes this even more powerful (any realtime updating database library would do the same). I just have to say where in Firebase I want to fetch the data from, and where that data goes in the template. From then on, my webpage stays up to date as the data in the database changes (regardless of who changes it).

Try use Knockout.js. I also don't like the heavy weight tools like Bootstrap/Ember/Angular with their my-way-or-the-highway approach. Knockout.js does bidirectional two-way view-model binding and other MVVM goodness without insisting you have to abandon other tools. You can use other template engine easily.

I can only assume you've never actually used Backbone (Which I also assume is what you meant when you said 'bootstrap'). It's neither heavy or "my way or the highway."

Knockout is great, but the two-way bindings do come with a non-trivial performance impact.

I switched from Knockout to AngularJS.

Knockout basically thoroughly entangles itself with my model -- I have to wrap my attributes in ko.computed() or ko.observable().

That makes unit testing messier and leaves me constantly trying to remember what is left as .dataAtttribute and what's been transformed into .dataAttribute().

I have to declare the bindings in Angular also, but after that it largely leaves my code alone. I shaved about 10% off my model code when I switched.

I also switched from Knockout.js to AngularJS - my code's so much cleaner now, without having to wrap my model in functions.

You can switch the template engine in Ember, but you'll lose the databinding hotness unless you implement it in your own engine.

Do they provide some kind of spec/API for other engines to support it? That would be a killer feature.

Yeah, still waiting for jade support but haven't looked at how to implement one yet.

You might want to give Emblem a shot. It's similar to HAML or Jade but compiles to Ember/Handlebars-compatible templates: http://emblemjs.com/

Everytime I read an Angular postmortem I'm intrigued that I never see memory issues being raised.

In a recent rewrite of one of our applications into Angular we had huge issues with it consuming memory. I think our use case is quite distinct, we have a telephony component that needs to stay loaded so single page app really does mean single page app for us, but even so I would expect to see memory mentioned every now and then.

I haven't had significant memory issues with Angular. Have you profiled your app? Where is the large portion of memory being consumed. The apps I'm building are being deployed on an embedded system with a custom WebKit -- where the memory constraints are significant (the hardware has a total of about 400MB RAM for everything) -- so I'm pretty conscious about memory issues, and we did test/profile Angular on this hardware and did not find issues.

That isn't to say you still can't shoot yourself in the foot with Angular (especially with something like ng-repeat). There are ways to code an Angular app with an eye on memory / performance, and there are ways to do the opposite, but I don't feel like the framework itself introduces significant overhead.

It seemed it was detached DOM elements that were causing most of the problems. We tried profiling with the Chrome dev tools but found it very difficult to pinpoint where to start looking from the thousands of elements generated every-time we repeated our workflow.

In the end we looked at the bottom line memory consumption and experimented until we saw reductions. We found using things like ng-show instead of ui-if, essentially preloading the partials and switching between them instead of reloading everytime, saved us enough memory to make the system viable.

We've had similar problems before (outside of angular), and the lack of visibility and tooling is horrendous.

However, at Google I/O they demoed the new object allocation tracker, which seems like a vast, vast improvement. Highly recommended for figuring out where memory is leaking and what code is causing it.

Here's the session: https://www.youtube.com/watch?feature=player_embedded&v=...

Still pretty primitive, but progress at least.

our app is... big. It runs great on "modern" devices and browsers, and we haven't had any severe memory issues. We profile on a semi-regular basis.

I can't show you our app as it's internal but in my travels I found the Dairy Queen site exhibits similar behaviour. https://www.dqcakes.com/#/home

Get through to where you pick your cake design and pick one, then go back, repeat and watch the memory increase.

I'd add a few more thoughts.

Keep your controllers lean and mean. Put more of the UI logic into services. This makes testing a lot easier.

Only use routing ($route, $routeProvider) if your app has very little UI state and could reasonably thought of as several totally independent pages. I switched to managing $location.path() explicitly and haven't looked back.

Embrace promises throughout your app. Angular templates can now render promises naturally but I've found that I prefer to be more explicit:

  $http.get(url).then(function(response) {
    $scope.something = response.data;
  }, function(error) {
    $scope.$emit('error', error);

Wrapping jquery widgets in directives often results in more code than just doing it yourself. Obviously this increases your maintenance surface area but typically less than you would expect.

The Angular Bootstrap project is trying to create directives that avoid jquery and could be bound (with different templates) to other UI frameworks. What I really want is a core set of UI widget directives and then separate (bootstrap or foundation inspired or not) CSS libraries for styling them.

really good points. We were "promise shy" and I'm now completely sold and in love with them.

We actually use a Command implementation that I ported, which has been really handy for leaning up the controllers, plus they aren't stateful so they are always available. https://github.com/joelhooks/js-command-center.

Took his advice and opened up a random angular source file. Found this fun, little snippet:

  // String#toLowerCase and String#toUpperCase don't produce correct results in browsers with Turkish
  // locale, for this reason we need to detect this case and redefine lowercase/uppercase methods
  // with correct but slower alternatives.
  if ('i' !== 'I'.toLowerCase()) {
    lowercase = manualLowercase;
    uppercase = manualUppercase;
Looks like Angular is more battle-tested than I would expect..

Ahh, Turkey strikes again! The Turkish locale is notoriously difficult to handle for a variety of reasons. One of my colleagues wrote an excellent post about the different ways that Turkish conventions can break your code: http://www.moserware.com/2008/02/does-your-code-pass-turkey-...

This seems to be yet another one!

The date format and digits separators issues are not at all specific to Turkey. The only thing uniquely Turkish in the "Turkish test" is the treatment of the case of "i" with and without a dot.

That's actually wrong unless that i/I code is strictly internal data which is never shown to a human. Where was the snippet from?

In Turkish, "i" uppercases to "İ" (note the dot) - there's a separate undotted lowercase "ı" which becomes "I":


So basically if your goal is for "i".upperCase() to produce something which goes to another program (e.g. an API call), the Angular code is correct. If it's going to be displayed to humans, it's wrong. The documentation at http://docs.angularjs.org/api/angular.uppercase should probably specify that this cannot be used for user content.

It's a weird comment because the definition of "correct" is not specified. Is it a workaround for a bug in Unicode or a bug in its implementation?

The bug is developers not realizing that a capital "i" is not universally constant. That is, there is no bug in either unicode nor implementation. Just something highly non-obvious to the rest of the world.

Having just built a hobby Angular.js app, it's cool to see that it fits large aims. For personal use, I found it incredibly refreshing to use, even as bizarrely different as it was to anything else I've tried. Not in a bad way, but in the sense that it was more convention than I was used to (outside of Rails)

I would add that the Yeoman build manager is an absolute delight to structuring and managing your project. It was so slick that when making my first Angular app, I also ended up learning CoffeeScript to kill two birds at once...Yeoman made this otherwise prickly situation as smooth as possible.

And I also would agree that directives are Angular's killer feature...and unfortunately for me at the time, one of the hardest to grok because of their magic. Anyone writing an Angular tutorial would do a great service to emphasize the power and use cases for directives.

you absolutely should look at the videos on egghead.io about directives. they are a must read as they go very deep into the subject while keeping things extremely easy to understand.

re directives

two places really helped me go from wtf to, "hey I can do that!" (and now I'm onto transclusions)

http://www.egghead.io as mentioned

and the Angular meetup video about directives: http://www.youtube.com/watch?v=WqmeI5fZcho

The documentation for Angular is dense. As in I've found myself having a lot of "ahah!" moments from reading 3 words.

I'm actually starting to annotate it on my blog as I find stuff out.

All that being said, I'm using Angular to make single page app prototype very quickly, coming from having no experience creating single page apps, but with a fair few years of MVC under my belt.

The angular internals is another great resource for directives, as the framework itself uses them heavily.

If you don't mind, what is your blog? Thanks.

On this project we are saddled with Maven, you are right. I am gonna add a section on build.

I found this helpful in understanding how to use directives:


Can anyone point me to real world AngularJS project with a healthy amount of unit and end-to-end tests? I've read the tutorials from official site and elsewhere on the web but they seem to stop after showing how create a controller with mock $http. As a relatively novice JavaScript developer, I'd like to see more comprehensive examples with mock services etc.

I too have built a reasonably sized Angular app in the last year [1] and echo a lot of these thoughts. I'll add a few of mine:

1. For CSS, honestly for any project it'd be hard for me not to simply use Bootstrap and be done with it and then do the minimum CSS possible (I say this as someone who has been doing CSS for years). Bootstrap really is the de facto CSS for the modern Web;

2. Organization: I agree the angular-seed project (which I started with and still use) isn't suited to organizing large projects and I agree separating into functional modules is the way to go;

3. Directives are awesome but to get all the two way data binding working requires a fairly deep understanding of how they work (to get the correct combination of scopes, transclusion, etc);

4. Directives also have limits that are sometimes annoying. You still can't generate definition list items with an ng-repeat, for example (a template has to have one top-level element). A solution to this is coming;

5. There's no good way of both just including code and using the parent scope plus some extras. This is done for reasons of code separation but there really is a use case (IMHO) for includes vs imports for templates;

6. $resource has no HTTP PUT method;

7. I'd probably avoid $resource altogether although it looks attractive. Use rich objects [2] instead;

8. Angular allows you to use a bunch of different other frameworks but it doesn't always play completely nice with them. Take the popover in Bootstrap. The way this works is by moving an element around in the DOM. This doesn't lend itself to a "nice" Angular directive (my version at least is kind of a hack).

9. Underscore.js is awesome. Use it;

10. Try to limit yourself to using jqLite that Angular comes with rather than full jQuery. This isn't really possibly with any reasonable part of Bootstrap however;

11. Isolate scopes in directives results some weird and unexpected behaviour. For example, if you reference something with an attribute, it'll work if it's an object (including an array) but won't with a simple value, requiring you to put such values in objects just so the directive can get a reference to it. This tripped me up a few times;

12. Scopes aren't always truly isolated either. For example, you can get tripped up by this if you have two attribute directives on the same element.

[1]: for those who follow IO, I am the Tech Lead of the Open Bidder project at Google (http://googleadsdeveloper.blogspot.com/2013/05/announcing-op...)

[2]: http://stackoverflow.com/a/11850027/18393

$resource is really cool, but a bit half-backed. I recommend you check out Restangular, it makes using $resource a lot easier. https://github.com/mgonto/restangular

Amazing. Was just in the middle of implementing my own resource factory but this one looks like just the ticket. Dropping it in to my project now. Thanks, you've probably just saved me a couple of hours.

      10. Try to limit yourself to using jqLite that Angular comes with rather than full jQuery. This isn't really possibly with any reasonable part of Bootstrap however;
Can you explain this better?

Angular renders the most used parts of JQuery useless, if you use Angular the "right" way. If we do consider it, two of the most used parts of JQuery are $.ajax and querying the DOM.

Because angular already provides you $http and $resource which are more than capable of doing everything that $.ajax does - $.ajax and all its variant that JQuery brings in become redundant.

Because of the way Angular is and because of its philosophy of directives - You generally dont need to query the DOM at all most of the time ( like 90% of the time ). For the rest of the 10% of the time when you do need to query the DOM, you only need to go one step below a directives element (direct children). If you are doing anything more complex, then you are doing something wrong again. For this basic case, Angular already provides you JQLite which is capable of doing the querying for simple scenarios like this.

About the helper functions that JQuery provides - angular too provides quite a few helpers - and they are sufficient for like 95% of the cases. For other stuff you might want to consider underscore.

So, why do you need to include JQuery?

> So, why do you need to include JQuery?

Because it's the foundation of jQuery UI, and JQUI has modules that I don't feel like writing myself from scratch (sortable nested lists).

Still, the joins between Angular and JQUI (through AngularUI) are fairly visible. It's not a smooth ride at the moment.

If you don't include jQuery then Angular falls back to its own home-grown mini-jQuery that they call jqLite, which contains a few essential functions of jQuery. GP was saying that it's sometimes wise to try and only use jqLite if you don't really need some more advanced parts of jQuery. This is presumably to save bandwidth.

jQuery is very large if all you are using is the selector engine and some DOM manipulation.

I haven't written a for loop in 6 months. Underscore is the shit.


> 10. Try to limit yourself to using jqLite that Angular comes with rather than full jQuery. This isn't really possibly with any reasonable part of Bootstrap however;

unless you are coding all your js widgets from scratch that's not an option , and there is 0 reason to do it. jquery plugins are easy to integrate with angularjs directives , why not use them?

i used taginput, transit, autocomplete, masonry and bootstrap widgets to code this app : http://markme.alwaysdata.net/ ,are you really suggesting people should not use jquery? non sense. Angularjs is made to be used with jquery. Angulajs doesnt provide widgets , jquery + 10000 of plugins do .

Um,... no. Why would you want full jQuery and load additional X kilobytes of javascript when in reality, Angular enables you to develop same functionality that many jQuery plugins (via directives) with ease, and way less code. It's a bit more work, no argument there, but I end up with more maintainable code, organised as I see fit. Faster and easier debugging, less dependencies and faster load time.

And Angular isn't made to be used with jQuery (or not to be used for that matter). In fact, it's advisable to completely remove it in order to fully understand, appreciate and use Angular's internals. Otherwise you're using two huge frameworks (in terms of KB and complexity) and only use small parts of them.

> And Angular isn't made to be used with jQuery

Depends what you mean. Angular will use jQuery instad of it's internal jqLite if it's loaded.

So tell me, how do you make visual effects without jQuery? jqLite doesn't support half of the things I need.

I agree on this. Angular is awesome for organizing large JS, and making re-useable components. Directives are a killer feature, along with DI (to facilitate testing) and 2-way binding (to eliminate all the boilerplate glue you'd have to write with something like Backbone). The team I'm on recently set up a fantastic Grunt build that incorporates Jade, Stylus, Angular, Google Closure Compiler along with testing infrastructure that works with CI/Jenkins using Mocha, Phantom, Sinon, Chai. It makes developing web apps fun again.

Right now, we don't pull in any other libraries aside from Angular. We've found we don't need jQuery anymore, and are able to build up re-useable widgets with directives and use them across projects.

Re-usable widgets with directives sounds great but the problem I have (with widgets in general?) is that every situation requires a slightly different widget which means the directive gets polluted with conditionals and stuff. For me it sounds good in theory but never works in practice.

I too have built a reasonably sized Angular app in the last year [1] and echo a lot of these thoughts. I'll add a few of mine: 1. For CSS, honestly for any project it'd be hard for me not to simply use Bootstrap and be done with it and then do the minimum CSS possible (I say this as someone who has been doing CSS for years). Bootstrap really is the de facto CSS for the modern Web; 2. Organization: I agree the angular-seed project (which I started with and still use) isn't suited to organizing large projects and I agree separating into functional modules is the way to go; 3. Directives are awesome but to get all the two way data binding working requires a fairly deep understanding of how they work (to get the correct combination of scopes, transclusion, etc);

One of the issues I struggled with while toying around with AngularJS was how to load the many scripts (controllers, directives, etc.). Is there any suggested reading out there on how to perform this without just including a bunch of script tags on the page? Or, is this considered more of a build tool problem, where the scripts should all be concatenated, then loaded as a single file?

I use require.js for this. There are a number of seed projects out there to get you started, but I suggest not following them too closely. Once you understand the basic technique it's easier to figure out your own organizational structure. My main suggestion is to discard the seed project's suggestions of organizing things into directories like /controllers, etc., in favor of organizing the files around specific screens. This reduces friction when it comes to using things like route resolves, which are a huge pain if you have the routes in a routes.js and the controllers in controllers/MyController.js.

Thanks -- I had tried going down the requirejs route with all controllers loaded into a 'controllers' module, directives into a 'directives' module, etc., and felt like I was writing way more boilerplate code than should be necessary with a framework like Angular. I'll have to revisit using requirejs with more of a page/functionality-oriented structure.

Yeah, I don't get that approach at all. I started with that, ran into a case where I wanted a route resolve, couldn't figure out how to do it without a huge amount of hassle, and ended up reorganizing around screens. I do still have global services, directives, and filters, but I define them as close to screens as I can and only pull them up to a global scope when necessary. The module-per-screen approach makes a lot of sense from both Angular and Require's perspective, I think.

We use the optimizer as well, during our build process, so you can use require to load everything during development and then optimize everything down into a single file later. The optimizer is pretty powerful and supports several different scenarios for doing this.

Dont use requirejs,it solves very little problems. Have a dev distrib where you pile up js files and templates, and a prod distrib where your files are "merged" into one. Requirejs is a nightmare to use, especially with the angularjs ioc container. Remember you can reopen the same module in different files.

I'm working on a large angular project right now, and we're using Usemin[0] for this. Basically you have your dev version of your html page, including all your scripts separately - and when you run a grunt task, it concatenates all these scripts into one and rewrites your <script> tag accordingly.

[0] https://npmjs.org/package/grunt-usemin

If you like directives in Angular.js but use Backbone or simply want something which is not so much opinionated then you might like to take a look at Backbone.ViewDSL[1] which provides data-binding and custom directives for Backbone.View

[1]: https://github.com/andreypopp/backbone.viewdsl

I liked the part about structuring the code/files. As you, I'm not a fan of the seed-app where you have one js file for controllers, one for directives etc. Makes it hard to find the stuff I'm looking for, and there will be merge conflicts.

thanks for the post. this was a good read. I'm about to start work on a medium sized Angular project and this kind of thing is very helpful.

I didn't see any mention of your backend for the project, but I did get the impression it was something Java (why else would you be using Maven?). I'm looking to be writing angular templates on top of a django backend (supplying a RESTful api for data access). I'd love to read more about integrating Angular with RESTful backends.

> I'd love to read more about integrating Angular with RESTful backends.

If your backend exposes a textbook REST interface, integrating it with AngularJS is almost no work at all. $resource is all you need. In case you have one or two non-RESTful endpoints here and there – and honestly, who doesn't? – $http is your friend.

In an app I'm working on, I have a front-end built with Angular talking to a Tastypie back-end. Since Tastypie implements all the boring REST CRUD for you automagically, integrating the two took about fifteen minutes total.

If there are there any specific questions/issues on your mind, ask away.

Do you have an example of TastyPie and AngularJS working together? I've got a straight-forward CRUD app (mostly) that AngularJS will be great for, but wrapping my brain around it all and an API has been difficult.

Unfortunately, I don't know of any such examples.

Here's something I found while Googling around: https://github.com/dalcib/angular-phonecat-mongodb-rest. It doesn't use Django and Tastypie, but you may find at least the front-end code educational.

I personally completely separate my front-end and back-end code. So while the API is built with Django, the front-end doesn't go through Django at all. It's served straight through nginx without doing anything special except maybe some simple URL rewrites for prettier URLs.

If I'm not too tied up in college work this week, I might do a write up on Tastypie and Angular integration.

thats great. thanks. I'm still learning about Angular and had been using $http pretty much raw for most of the data fetching. I started to play around with $resource but didn't get very far due to some frustratingly vague documentation on the official site.

Do you know of any really good tutorials emphasizing Angular's $resource service?

> Do you know of any really good tutorials emphasizing Angular's $resource service?

Not really. I just used the official documentation. The egghead.io tutorials may touch on $resource. I also found this helpful: http://www.bennadel.com/blog/2433-Using-RESTful-Controllers-...

Some Googling turned this up: https://github.com/dalcib/angular-phonecat-mongodb-rest. It may help you.

I really think AngularJS with Firebase is the future. Using Firebase makes you app real-time, with no additional development.

When you don't have to write any server side code at all, it can really speed things up.

thanks for the tip. I just checked out their demo page and it looks pretty sweet. I'm mostly still working on applications that have plenty of relational data and server-side data processing, so I don't think Firebase will be of immediate use for me, but I'm definitely impressed. The speed and ease is very nice.

Can someone explain why I should use any of the tools listed in The Build? Why do I need to add that layer of complexity?

I added it based on a comment. Yeoman is interesting because it has "rails like" generators. This can be nice on a project of size, for consistency and saving time.

Yeoman uses Grunt, which is nice for building, watching, and packaging.

Not strictly needed, but very useful and recommended.

We learned the same lessons with the chat function Babblr. Structuring the code/files is highly affective.

Wow. Strong opinions on both sides of the debate.


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