Rant: Backbone, Angular, Meteor, Derby
gist.github.com
gist.github.com
* I started out with Backbone. It seems ok as far as it goes, but a bit annoying in that there's enough "magic" and stuff going on that I don't quite understand it completely, but without enough magic to really make things simple and easy.
* Angular.js. Now this is more like it in terms of magic. Then, the other day, I decided to add a date picker to one of my forms. Uh oh: http://www.grobmeier.de/angular-js-binding-to-jquery-ui-date... - how many lines of code just to make it a date picker? I couldn't have written that code myself without several more days of banging my head. Wonder what'd happen if I really try and do something it doesn't agree with... So out the window with that for the time being.
Also: a lot of these tools have tutorials that don't really walk me through all of what I want to do, which initially involves a fairly straightforward "CRUD" type of application. I want to see how the framework deals with both 'make me a new one' and 'edit an existing one' forms, for instance. I found that very irritating about the Angular tutorial, which is otherwise very nicely put together.
Now I'm testing out jquery-pjax, and... so far I'm happier. It behaves more like a web application that I'm used to, sending around HTML, and staying out of my way. And, seeing as how all of these things require that the server do its job in any case, it has more of a "don't repeat yourself" feel to it: click on the button, and the server gives us some new data, without repeating the whole MVC cycle on both the client and server. I got the idea from this post: http://37signals.com/svn/posts/3112-how-basecamp-next-got-to...
Couldn't have said it better myself. I can't count the number of times I had been excited about learning some new framework, only to discover that their documentation is non-existent, poor, or written for rocket scientists.
What happens to SEO?
Wouldn't that suggest that any search-engines wouldn't have an issue indexing your site if you implement things correctly?
now, i'm back to plain javascript/jquery. i run into less headaches and more control, therefore more productive. my gripe is the same as op, the "magic" is what throws me off. angular is a bit too buggy, last i used was 6 months ago, and still lot of things they didn't support like proper callbacks upon rendering, etc ...
basically something really easy to do in plain js, becomes like a rubik's cube with all the magic going on. just be prepared to write a lot of extra code/hacks/patches for certain things to just "work" if you decide to go the i.e; angular route. but don't say i didn't warn you :)
>and still lot of things they didn't support like proper callbacks upon rendering, etc
Heh render callbacks in Angular? That's so Backbone. Did you read the hello world tutorial?
also i don't know why not too many people bring up such issues as the 'if/else/switch' flagging nightmare that comes with maintaining an angular code-base. it makes your code a very verbose in that regards.
To be fair, you can just use Angular UI as that article says: <input ng-model="date" ui-date> for a date picker and the ui-jq directive for any other jQuery plugin.
I'm ready to get on board with something cohesive that's Ember-ish whenever it matures.
This is one of the lines in backbone.js:
if ((callback && callback !== (ev.callback._callback || ev.callback)) || (context && context !== ev.context))
I feel stuff like this takes a lot of mental power to understand the context that it is being executed in and what exactly it is doing. It feels like I am knee deep in some obfuscated C code.
It definitely gets the job done; however, I would imagine someone figures they'll come back and refactor at some point. Code is never finished, it is merely shipped. This is shipping code, but it certainly can be refactored into a more intention revealing function.
It's a trade-off. If you pull it into a new function, it adds LOC. It also is another layer of abstraction. Is it worth it? Perhaps...but maybe not. Just looking at this one line of code in isolation without context is a bit unfair though.
As it happens, I just completed a 4 part tutorial building an Angular CRUD app this afternoon! http://jphoward.wordpress.com/2013/01/04/end-to-end-web-app-...
The backend in the tutorial is in C#/WebAPI, but it's very easy to apply the concepts to any server - the server is tiny and very simple. I'll be doing a Python tutorial with Flask-Restless very soon.
I'd be interested to hear any feedback. I'll be adding video wall-throughs in the next week or so too.
However, as our Backbone application grew in complexity, we noticed that Backbone is so bare in terms of functionalities that we had to build our own half-baked framework on top of it to make up for the gaps.
I think the Backbone project needs to make Backbone's intentional feature sparseness clear. I've come to realize that backbone is more of a library which provides a basis to make a client-side framework rather than a something that can be used standalone by app developers.
If I could go back and change our original choice, I definitely would have gone with one of the Backbone-derived frameworks (chaplin, marionette) or just gone with something more fully-featured like angular. While backbone is beautiful and elegant for small projects, it just doesn't provide much convenience as a stand-alone library for larger applications.
1) https://groups.google.com/forum/?fromgroups#!forum/angular
2) https://plus.google.com/110323587230527980117/
3) https://plus.google.com/communities/115368820700870330756
4) http://webchat.freenode.net/?channels=angularjs&uio=d4
5) http://www.youtube.com/user/angularjs
Here's the guiding principle behind Meteor. There should be a dramatically faster, more accessible way to write applications. Improving that developer experience means rethinking some things: autopublish and minimongo, so you can jump right into a new app's UX in the first five minutes; one-line authentication (http://meteor.com/authcast); synchronous APIs that are more comfortable for a lot of developers; dirt-simple reactive templates; hot code push.
Focusing on that kernel of development experience means some other things -- REST, routing, form building -- need more time to fully bake, with hacks like __meteor_bootstrap__ and phantom for apps that need them now. We think that's a good tradeoff pre 1.0.
So, in a way, that's great! An mental orgasm for any nerds out there. But in the real life when shit needs to get done, I'm still using everything else that sucks.
Now, before people start saying I don't know what I'm talking about, here are a few examples: - It does NOT use npm (!) -> Basically, you can't use anything without first converting it to Meteor. - It does NOT use Express (Or connect) as its base -> Basically, the standard in the Node community. That means I can't just plug-in the 20 or so awesome plugins built explicitly to be used by any kinds of node application that support connect.js - The current Asynchronous (following node's philosophy) wasn't good enough for them; so the re-created a whole new Mongo version acting synchronously.
But most importantly, it's just extremely annoying to hack with it. It's like a big black box.. you're not very sure what it does and you hope it works. But when it's not working, you can't just hack it your way or read the source. It's a little bit like Django or Rails (but in worst) as you can use SQLAlchemy in Django, or you can use different template engines, but then no project from the django community will work with your app.
The good news is, the meteor team is working hard. Maybe in a couple years it will be stable enough and iterated fast enough to provide a platform where it will be fun hacking and building web apps. But for now, I sadly prefer to stay in the "Everything else sucks" world and hack my way in the node jungle.
(For those interested, I have also tried Derby. As said in the article, it's not yet fully stable and the documentation is really Meh. But I think it's going to be big really soon and I'll be more than happy to give it another fair try. So far, I'm sticking to a basic express (Or locomotive.js which is nice.) I'm also using Angular.js on the front-end. It's something amazing as I feel very productive and it saves a tremendous amount of time.. but at other moment, I just bang my head against the table as I want to do something simple and it's just impossible so I need to use all kind of hacks to do what I'd have done in a couple lines in Vanilla Javascript. Oh well. Hard to be a hipster web developer trying all new technologies :-))
Nearly all of the Meteor code is broken out into various packages. They implement components like publish/subscribe, client-side data caching and snapshotting, reliable remote method invocation, live page updates, and hot code push. They're the building blocks for a rich client application.
Now, we have some work to do on better separating those components so that you can pick and choose the parts you want, like using livedata (publish/subscribe) with Angular, or using Spark (our reactive page update engine) with a legacy REST endpoint instead of livedata. Those combinations are technically possible today, but not particularly accessible. They should be.
(That is one of the two front-burner project we have going today. The other is scaling.)
You say "like using livedata (publish/subscribe) with Angular", but that's the problem I'm talking about. You need to tweak the system to make it work with Angular. But what about the hundreds of other smaller angular-like libraries? Or tomorrow's most popular one? I can't just <script src="it">, I'll need to create a meteor package and make sure it works good with all the rest of the system (Which unless I'm a Meteor expert, I have no way of knowing).
That could actually be a good blog article, "How to use MooTools, django template system and MySQL with Meteor". I.e. Going through what's needed to be tweaked to make it work. Compared to say, express, I could tell you use the mysql node library, normally include mootools in your html files and use mustache (Or whatever library already exist to mimic Django's libraries).
You do realize this is the holy grail of software development? The thing we've been seeking since, oh, at least the mid 1950s.[1] Pretty ambitious to think you'll crack the nut, at least more than momentarily.
Copying is dramatically faster than doing something new.
Here's a long list of examples why maybe it should be:
http://backbonejs.org/#examples
In comparison, here's the public list of interesting apps built with Angular and Derby:
http://builtwith.angularjs.org
https://github.com/codeparty/derby/wiki/Community-Projects
What you want to look for in a library goes beyond feature checklists and magic datepickers. Lots of client side developers have been burned in the past by JavaScript frameworks that promise the world and end up getting in the way more than they help.
Backbone tries to provide the barest useful essentials -- the main business of building your app is up to you.
I personally prefer minimal frameworks because they don't assume what your finished product will look like. You can grow the application organically rather than trying to fit it into some prototypical mold. Full-fledged frameworks have their uses - they are perfect for getting up and running on known problems. But if you are trying to bake things into an already mature code base or trying a totally different style of architecture, they are not worth the work.
"... use Backbone because it's the most popularl framework when it shouldn't be."
You bring up a good point...to add to it, many people also choose to go with YUI, Dojo, EXT when Backbone or a list of small well curated libraries would have been a better fit.
Essentially, the problem isn't Backbone or any of the other libraries/frameworks...it's that there are a LOT of developers that can't seem to evaluate the available options effectively.
http://returnbooleantrue.blogspot.com/2012/12/architecting-k...
I personally don't like backbone that much. I don't know why so many people love the damn thing. It is hard to understand and not even that great.
Extensibility & hooks: Extending built in behavior in Knockout was much easier than in Angular. Without getting into too much detail, one of the things I tried to do was create a list of items on the page with a simple animation for item removal. In Knockout, it was trivial. In angular it would have required a copy-pasta style rewrite of the repeat directive.
Some weird missing features: Angular has no conditional add/remove element directive (that I could find). This just seems like a weird oversight. There's a show/hide element directive, but trying to substitute that for add/remove will break CSS first/last/nth child selectors.
Angular has a lot of potential, but it felt to me like it needs a few more iterations before I'd want to try to build a rich UI on top of it.
Angular does have a conditional add/remove element. You can use ng-switch for that. If you are using CSS selectors in an angular app I sense a smell. Something is not right.
You're right - you could use ng-switch for add/remove. It's a bit awkward though. I'm curious as to why you'd consider "CSS selectors" a smell in an angular app. I'm assuming you mean some subset of CSS selectors (possibly just the first/last/nth-child selectors I mentioned?), as without selectors you can't really have CSS.
Can you elaborate a bit? Thanks!
Angular is great but the problem is you really need to use client side templating for it to be useful. It also has the same syntax as django's template language by default. All this is workable but Angular is great for projects that you are starting. Knockout is better to integrate with existing projects.
Also, in my tests for an app(PhoneGap) I did recently, it seems much faster than angular(rendering seems to take half the time)
It's an old and trusty way of doing GUI, but it require you to define your UI(views) in two places - HTML and js code. You must have hardcoded HTML references in your JS code(via CSS selectors & etc), and for every change you do in your view you have to check(and probably change) your js code as well - and vice versa.
Where in MVVM based frameworks(e.g. knockout) you define your view only once - in your HTML file. Your view contains everything that is needed to render the data in your View Model, and can initiate changes to the view model(and render any change that is being made to the date in the view model). There is never a need to use hardcoded references to the HTML in your js code.
I have tried most of the data-binding plugins in backbone.. They all fall short one way or the other. Stickit does not deal with collections, model-binder does but is a pain in the ass to use properly. Rivetjs seems better than the other two - but the scariest part of backbone plugins is that the community behind each is extremely small -hence its scary to consider them.
Angular is exceptionally flexible and one of the first tools for building client-side JS that really impressed me. That said it is fairly complex (and not that well documented) when compared to Backbone, so I can understand why not everyone would be impressed. Cavet emptor. As an alternative Knockout is pretty simple, it's just not my thing.
Backbone is a neat tool and what it provides most people is a somewhat predefined structure to work in. Coloring between the lines is really useful. However (as the parent said) it really does very little other than that in the end really. There is almost nothing that Backbone does that a sensible use of jQuery binding and data attributes can't do as well or better. It's just that most people will find it easier to learn Backbone, which is great don't get me wrong, but don't be surprised to find people (like myself) who have moved on.
(Also the way model are done is terrible, I've never liked it it always got in the way of whatever I was trying to do.)
<span data-bind="text: someVariable"></span>
may look ugly but it is very clear that there is a variable associated to this DOM element.
It took some time getting use to but once I realized how much it made sense I got over it.
So tell me about this universally better way to go.
OutbackJS makes it work like Knockout, but maps onto backbone models (disclosure: I wrote this one). Most of my models in production apps have zero complexity - a url property is usually all that distinguishes them, and outback bindings means that I a) don't have to litter my code with jQuery nonsense, and b) don't really have to muck with models beyond fetching and saving them.
I switched to Backbone and got going right away, in half a day of reading the docs and watching a couple of peepcode videos and I was off and didn't look back.
Maybe the Ember docs have improved in the last couple of months but at the time it was just a non-starter for me.
edit: I believe the issue was around Ember Data/REST. Out of the box it didn't support polling data on a REST interface, which seemed absolutely critical/fundamental to a JS framework. I found a plugin I believe called Ember Data, but documentation was very sparse and I couldn't even get a simple example going. This is going on memory so this could be slightly wrong or different today.
Still, once we've learned Ember we're very happy with it. Backbone is just too small to start any medium/large app, and Ember has a decent community behind it and lots of integrations with Rails.
The hope is to make it awesome for other JS frameworks too, but we mostly build Ember apps ourself, so you start with what you know...
You haven't seen the full power of AMS yet, but I have some exciting things planned. :)
Also you should look into active model serializers for integrating rails with ember. I think it's yehuda Katz' preferred method for Jason serialization from rails to ember.
That is true. AMS + Ember-data = 👍 (I'm now maintaining AMS, but Yehuda and Jose Valim originally wrote it for this purpose.)
But ember shines in other areas that people wont care about until they have to write single page web apps with a high enough complexity that warrants it. The reason we ditched gwt for ember was the 2 way bindings. Not having to write all that stuff(and test it(in every browser))has been a productivity boost, even though we had to plugin our own persistence layer.
So why is that? This was my big head-scratcher with Ember; surely the access to a data layer is the whole point of these javascript frameworks? I mean all backbone is really is a layer between REST and client-side javascript. I guess i'm missing a whole class of JS applications that don't need access to a server-side data layer, but for me that's the fundamental reason to be looking for a JS framework in the first place. So to come across one so highly regarded which doesn't have it baked in was very jarring.
It's not 'baked in' because Ember is modular: Ember-data has all of that layer in it, so the rest of Ember doesn't have to care. That said, I disagree with your parent: you shouldn't be writing your own data layer.
Exactly.
I don't want to feel "lost and overwhelmed" when trying to learn some new product, or having to Google every single thing. It is a wonder anything ever gets done. Seems these things are written by someone in their ivory tower without any forethought to documentation. "Someone else wants to learn it? Not my problem! I developed it, so there! No good documentation for you." That is just lame.
It's easy to get frustrated with ember & ember-data and just jump ship to backbone, but you'll be paying for it later when your data model expands beyond 5 interconnected models.
The best advice is to tough it out with ember even if the docs are weak and tutorials are sparse.
See, that's the problem. How do you get to "up and going" if the docs are sparse?
Just to be clear, this is not meant as a criticism of Ember, just a general observation that I have made time and time again when looking at new projects and reading comments saying things like "yes, X is not documented and hard to get into but once you get up and going it's all roses"
Not saying it hasn't been bad historically, just that it's getting better and will be good in the future.
The only time angular / knockout's html seems to be less "pure" is when the browser has already rendered the content. At which point pretty much no one cares about it. When you are debugging you have your source.. Its either mustache ( or similiar templating solutions! ) which are not even close to HTML or HTML with additional attributes.. I dont see how that makes a difference.
The fact that you do very little DOM manipulation with angular.js is one of its biggest advantages, IMO. Makes it easier to write maintainable and testable code.
edit: Also to you point about dom manipulation. The same amount of dom manipulation is happening. You just aren't in control of it.
I find this a pretty good metaphor for the backbone/angular/ember distinction, highlights that this complaint is the old "I can't imagine anyone needing more flexibility than I do, so those other people are obviously wasting their time". Nice parallels to PG's famous blub paradox essay as well.
If I had to choose the 'best' javascript development framework, I'd choose clojurescript, not because it's such a great tool in itself (it is a great tool, though still a bit immature), but because it forces the developer to write javascript in the best possible way: functionally, only holding onto state when it's absolutely necessary.
It's good that there are solid mvc frameworks out there for when they are truly needed, but when the average developer picks one up for a routine web app just because it's the hot new thing, he/she's walking into a minefield for no good reason. Javascript is at its best when it's just a dumb, fast bridge between your server and your ui.
There's a fuller explanation of our routing / REST plan here: https://trello.com/card/page-model-server-side-rendering-res...
The problem with Ember right now is the documentation doesn't align with the most recent public version, which will confuse the heck out of newcomers and frustrate people who are still learning Ember. You can however, check out master to get the new router implementation.
I'm personally making the jump to the bleeding edge for two reasons: 1. The old router API is very hard to grasp. A lot of unknowns as far as where domain code fits when building your application using the router. 2. I don't want to be stuck struggling to find documentation for an already difficult API to work with.
With all that said, Ember is worth taking a look at as far as an 'improved' MV* experience, but you have to be careful as it is in a state of flux.
The Meteor devs themselves will acknowledge that some features are lacking (I imagine that's why it's not 1.0 yet), but the roadmap looks very promising and I believe Meteor also has the right team to make all this come true.
I think the problem is people come into Backbone.js thinking it's a full fledged MVC framework for in-browser apps, instead you should think of it as a minimalistic set of tools with which to create your own framework (and in fact, a few actual frameworks have been released that are built on top of backbone.js).
One way to taxonomize frameworks is on how opinionated it is - Backbone.js is on the far end of the unopinionated side. If that's what you like, then Backbone.js is for you. If you want something more out-of-the-box, you should be considering the other options.
If you need more than that -- automagic binding using HTML data attributes via Angular -- it's OK to use another library.
- dependency injection: because everything is injected, it makes writing isolated unit tests very easy. It also makes it very easy to swap functionality in and out without affecting other parts of the app.
- two-way data-binding: most of the pain of being a javascript developer comes from managing and manipulating the DOM. After using angular, there is no way I will ever use a framework that doesn't automate this tedium by providing two-way live data-binding (knockout, meteor, and ember all do this). The best part about having less DOM manipulation code is that it makes writing automated tests easier and makes those test much less brittle.
- extending HTML: this is often a main complaint of angular. People say that directives "pollute the DOM" which I find to be a strange complaint, given that HTML is a declarative (sometimes) semantic language to begin with. HTML5 added a ton of new attributes and features yet nobody complained that these new tags were "polluting HTML". Angular simply allows you to extend HTML's functionality even further, and in doing so it makes it very easy to understand what an HTML template is trying to do without having to dig through any JS code.
- testing: the angular team made testability a priority, which I was something I always really appreciated about the Rails team. If you're not writing tests for your javascript code, you need to start. Having full test coverage in both end-to-end tests and unit tests has been a major source of stability for me and my team.
I agree with that statement regarding DI; however, have you evaluated whether you NEED a DI container or just DI?
Angular forces you into a container even if you don't need it. Is that what you really wanted? If so, fine, just be sure :)
In fact, here is a verbatim quote: "Angular is awesome. That is all."
And here's the technical basis of why Angular is better than Backbone: "Now, I'm not suggestion people don't use Backbone. Use it if it's what's needed for your project, or you yourself are a Backbone ninja. What I'm discouraging here is its popularity as the de-facto client MV*"
I've played around with Backbone and appreciate its structure. I've never used Angular but have seen many compelling posts on HN arguing why it is a better choice in certain use cases. This rant offers no evidence or elaboration. Is it now cool just to hate the popular thing just because it's popular? Even rants against Facebook and Apple have more substance than the OP.
It can be a bit daunting when you are not a JS rockstar : directives and services code architecture, designing views without straight conditional logic, understanding the full power of filters and expressions (I still don't), using jQuery plugins with it etc.
I don't even use routes or forms yet but I had no problem integrating it into a "classic" web app.
The docs need some work though, maybe with more example on certain part. But you can find great code snippet and videos elsewhere.
Am I missing something here? Maybe next time put some links into your rants. Apache Derby was the only one I found on Wikipedia.
People say Backbone & Angular are different use-cases, but I find so many people "graduating" Backbone and wishing they'd chosen a more robust framework. They say they want to start minimal, so they pick Backbone. You can be minimal with Angular. It's like saying "ms paint or photoshop? Well what are you trying to do?" There's only 1 or 2 people really trying to draw something in Paint, the rest "think" they want minimal, non-bloated software. The answer to the question is Photoshop.
Now, Rails v Node v Java, something like that - there are tons of questions to ask before making such a decision, there's no one-size-fits all. But I think there is a one-size in this particular case.
i'm not sure if you're freelancing an app as a sole developer, or if you're an early stage startup, or if you work on amazon.com store. and where your project is, in this spectrum, is incredibly relevant context when you're dissing a framework.
Not Apache Derby: http://db.apache.org/derby/
I've looked over the docs, and as far as I can tell there really isn't a model in Angular - not anything concrete anyway.
The docs seem to explain that any JS object is a model as long as you make some reference to it.
Or, is an angular Controller (+ some JS data structure) really a model.
Its quite confusing to me.
For example. Within my controller, I set $scope.username to "alex" and this will update any HTML bound to the value "username", within the scope, to "alex". Similarly, I can set, say, $scope.settings = {user: {username: "alex"}} and this will update any HTML elements (within the scope) bound to settings.user.username to "alex".
These are very simple examples, but they show the beauty of having plain JS objects as your "models".
If you are looking for something easy to use to get you going you just use one of the frameworks built on top of Backbone, I suggest Marionette.
If you are using custom elements, then you have to figure out a way for your templating system to let it through. In grails for example, you can override it in the taglib's to do that.