I think Ben’s experience has been repeated by quite a number of folks. I remember having quite a few false and frustrating starts with EmberJS myself.
Too many times I think new folks unfamiliar to the framework are prematurely dismissed as not having enough rudimentary skills, lacking basic programming experience, and sometimes treated with an undercurrent that they’re not smart enough to get it.
Usually by the time someone has opted to jump into Ember, they’ve done enough roll-your-own work to appreciate what Ember brings to the table. Embrace these folks as future contributors and tutors for those that follow.
The fact that one can go over to Meteor and “get it” doing pretty much of the same concepts, suggests the problem is somewhere between the communication of ideas between framework designers and the target audience. But we’ll explore that in a moment.
Frameworks are supposed to not only remove the tedious work, do the heavy lifting, but also be approachable. Given that many of the folks having problems do have experience with advanced JavaScript, functional design patterns, other web frameworks, something is amiss. A close look at EmberJS shows that it has elegance, so it’s hard to blame the framework itself. Something else is going on.
@thatandyrose nailed it. It’s the documentation.
Ember’s documentation is beautiful looking, and that’s deceptive, because its polish conveys a degree of comprehensiveness and completeness that actually isn’t present.
When I dug my heels in to learn Ember, I took a bunch of notes, with the thought that perhaps a book would roll out. At the time of writing this, I have literally 72 separate concepts in my outline that are prerequisites for learning Ember from scratch. Somewhere between five and seven are what I’d consider the crucial concepts for groking EmberJS, but because Ember unifies these together so tightly, it seems there’s a chicken and egg problem buried in there somewhere.
Aside from outright problems and inconsistencies, which the community accepts from version drift, the documentation appears to be written in the form of a reference guide aimed at someone who already knows Ember. It’s not readable sequentially, as it makes forward references to unintroduced concepts. Consequently, at a minimum it takes multiple readings. Thank God it’s beautifully hyperlinked …with a tiny number of links to chapters that don’t appear in the outline.
As a development resource, it’s great. As a user’s guide, it does very little to let us into the mindset and design decisions that were made and how the framework designers expected it to be used. Explain by example doesn’t always convey why.
To be quite fair, this is a common problem for opinionated frameworks. Conventions are more than just naming conventions.
Suppose you want to something slightly more advanced than just displaying a form with reactive values in a template: store something trivial and do it the Ember way.
That means learning ember-data; one can surmise that it does ORM stuff, and maybe you’ve got years of Hibernate (or something similar) under your belt already – you’re not dumb. Click on ember-data in the documentation, you get a list of classes …but what are they for, what do they do, which ones are internal, which doe you extend through subclassing, which hooks do you override, which must you, and which can you?
Click a class, and you get a list of methods, but not the order they should be called in or used (alphabetical isn’t helpful); which ones are common, what’s the design pattern this is a part of, what are the ranges for the parameter values, where are the examples? How do these relate to other classes?
Terminology could be better. Oh, store
as in data store, not as in a verb such as to store()
. Can I use just a model, or do I need a store
? What responsibilities does the class pick up? Which am I responsible for? Is the adapter thingy for the store, the model, or the application? Why do I need one?
If you’re familiar with Ember you may know the answers, having discovered for yourself, but the new person is going to be faced with hundreds of these kinds of questions. What seems silly or even nonsensical to you now is a legitimate question for the uninitiated.
Documentation’s purpose is to solve this problem. Right now, in its current state, it isn’t. Some day it will, Ben. Some day.
The documentation isn’t quite clear either with its examples. Again, it’s not the what or how, but the why. Take a simple example:
MyApp.Store = DS.Store.extend();
store.find("person", 123).then(....)
Is the .Store
in MyApp.Store just a name I made up, or is it somehow wired where Ember by convention expects to see it? Why are we subclassing if we’re not adding anything to it? Why is DS
not in Ember’s name space? When did the store
instance get made? How did it get into scope? What naming conventions do I need to know? What is “person” the find is looking for? Does it do pluralization? Does that map to “People” somewhere else that I need to be concerned with? If a Person
class expect a JSON object with “person”, why did REST becoming /peopl
e. Maybe .fmt()
is guessable as format, but .loc()
, what’s that – location? an offest? or localization?
Note the set of novice question has nothing to with things like “what’s a Promise?” You’d figure that’d be the hard part. If they can get what that’s doing, then what they’re really asking is a better understanding of how Ember is put together.
Yes, the answers are out there – spread all over like a massive Google treasure hunt.
And this is the point where things get snotty, and the community says “go read the code.”
The code, frankly, is pretty brilliant. And that’s turns out to be a problem, too.
Library authors are super-talented coders, using advanced constructs and techniques, and are focused on concerns like size, performance, and reusability, taking advantage of state that’s not transparent in the higher level abstraction. Sometimes the implementation of simple API magic is some hardcore under the hood stuff that requires detailed knowledge of other system internals, like how the browser really manages the DOM. A novice might not get it, the same way as someone learning C might not get clarity by reading how the compiler emits assembly code while mixing concerns with instruction timing optimizations.
More over, if the novice is only familiar with JavaScript from a web-client perspective, an excursion into NodeJS, Ruby, compilation tool chains, package managers, dynamic loaders, and ES6 transpires are most likely things they’ve never encountered before. Let’s be fair when we dole out that advice. EmberJS should be for the masses, it doesn’t need to be the framework of the elite as it’s sometimes treated.
One of the things that I really respect about Meteor is that it doesn’t just throw an API at you. It’s documentation explains the foundational concepts first, building them up with trivial JavaScript code, and when you see how it goes about doing it, it then says something along the lines of Meteor saves you from doing all this with the xyzzy() function, but the actual implementation takes into account a number of additional edge cases you don’t need to worry over. The actual code is far more impressive, but you’ve got a metal model that’s usable immediately. I think that’s how Meteor gets an accelerated head start over Ember, even though it’s doing both the front end and the back end.
That said, in using Meteor, there’s a lot of freedom it gives that makes me long for how EmberJS opts to do and organize things.
So Ben, you’re not alone. And I’d encourage you not to give up on EmberJS entirely, but consider taking a break from Ember for a bit.
If the concepts are tripping you up, go read Meteor’s introductory materials, it will turn the light on for you – and you’ll see the parallels, at least conceptually, that Ember is also doing. Then come back to Ember, and I think you’ll like the way Ember has carved up the problem space and where responsibilities lie once you start using it.
If the convention is tripping you up, welcome to the club; working example projects are probably going to give you better insight than the documentation for now. Where Meteor has what appears to be a lot of stuff floating around globally, EmberJS has things nicely packaged into a namespace. Although, you’ll often be left wondering if you’re just using the name space as a registry or actually plugging into something by convention hidden in an implementation class – for now a lot of reading of the documents will help, but I’d rely on asking the community to get clarity.
In the end, I think you’ll really enjoy using Ember.