Why i'm leaving ember

Also, I wish someone would lock this thread as it’s just a sound board for negativity.

So I agree there has been some negativity here. But I do think there is value in understanding the stumbling blocks for people who want to and are trying to use Ember. For veteran developers on any tech stack it can be hard to appreciate the hurdles novice developers experience. Maybe this is forum isn’t the right venue, but I don’t think it’s good to be dismissive of people who are just trying to provide feedback and vent their frustrations.

8 Likes

I’m frequently told I’m being negative / off topic when I vent my frustration. At least here I’m not off topic. Why do so many people not want to hear criticism and negative feedback? These are vital if you want to make Ember better.

8 Likes

So, while I would agree that I have seen some of that within the Ember stuff, I have actually had more that were willing to listen and try to actually respond.

But the reality is, stackoverflow (and every similar website) is filled with the “why do you want to do this?” responses for every langauge/framework combination out there, not just Ember. If people can do that with things from PL\SQL, Java, PHP, Python, Angular, HTML, etc… then their is no reason to believe that the same thing will never happen in Ember.

I’m not saying don’t raise issues and discussions, it’s why I come here every day to try and answer as many questions as possible. What I’m saying it’s become difficult to follow this thread and is passed the point of a constructive discussion. Individual threads asking questions where people can enumerate on will yield better results

Fair point. I won’t disagree. I have my opinions on ember-data as well, and typically am the one convincing people not to use ember-data. Any case, you should look at ember-cli-simple-store - npm

Look, I see where you’re coming from. But at least for me, this is about trying to give constructive feedback for a framework that IMHO has potential, but also several important flaws. It’s not a specific issue, it’s about the bigger picture, and I think that’s very important too.

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.

@wls: I’m just starting out with Ember (coming from Ruby on Rails, hoping to use it with Rails). I know you’ve been asked this before, but would you be willing to share those notes you made during your learning of Ember? I think most of us who are diving in would really appreciate some hindsight from someone who has walked this road before.

Only by being mature to take negative feedback and process it in the light of positivity will something be improved. If emotional maturity is low then something that can be improved might be taken in as an attack or something subjective derailing the benefit of the constructive process…

Thanks @Gaurav0 for the contributions! :thumbsup:

4 Likes

I don’t want to lock this thread, but this thread seriously has just devolved into a dumping ground for people that have probably spent 0 time reading the docs or seeking help. The number of complaints in here for “how do I” that would have been solved within a minute of googling / docs reading is absurdly large, and only makes people think there is a problem where there isn’t.

But the reality is, stackoverflow (and every similar website) is filled with the “why do you want to do this?” responses for every langauge/framework combination out there, not just Ember. If people can do that with things from PL\SQL, Java, PHP, Python, Angular, HTML, etc… then their is no reason to believe that the same thing will never happen in Ember.

I dive in and answer questions on Slack and SO more than most, and I ask this question a lot, not because I disapprove of their doing something, but because context for a question very very much matters. 99 times out of 100 I ask that question, it turns out the person has turned something very simple into something overly complex by overthinking a problem they don’t have. There aren’t very many hard problems in Ember, so when someone thinks there is, I tend to need to figure out what it is they actually want to accomplish in order to show them how to do it.

Not compared to many others, so especially if you’re on the slack channel, you always see the same couple of people.

Our active engagement on Slack is actually very very high, but several of the admins (myself and Locks) intentionally make ourselves available for much of our day to answer questions, and many of Ember’s core team members also frequent Slack (such as rwjblue) in order to keep the entire community available to everyone.

I’ll be willing to do that when Ember stops advertising Ember Data and takes it off its guides and API docs. Being honest about Ember Data

We all have issues with ED, but if we did this it would never improve. It’s still the best data layer out there, and getting to be more so entirely because myself and lot of others actively point out flaws and suggest alternative approaches. Over time, those flaws and approaches get coalesced into a working solution. ED is down to just a few flaws (and some more visible docs on the attrs feature) keeping it from being a very robust and edge-case tolerant data layer.

The reason I don’t recommend anyone look at other data layers anymore, is because there isn’t another one that’s nearly as good. Ember-orbit fizzled, the devs I know using pouch have had to do most of their own maintenance there, ember-model is unmaintained, ember-simple-model/simple-store is not feature complete enough for most apps, falcor is new and largely untested, redux has it’s own issues with performance and immutability and doesn’t solve any of the problems ED has remaining either.

Try to understand what the person is trying to communicate, and how it fits in with Ember concepts. Obviously, this can be difficult if said concepts are already hazy, but you’re probably staring at a strong hint. Hit the docs again.

This is a VERY good point. One of the things the Ember community really has going for it is a level of politeness, maturity, and willingness to help anyone (even the most basic of beginners) find their path to being an expert. It’s (usually) not likely for a reply to be snide, we just need to find the right question to answer. (I’m human though, and sometimes I’ve had a bad day, and sometimes I’m a little snide, and when I am, I apologize and then stop answering new questions until I’ve had more coffee and a snack).

Please don’t pretend you know every use case. The person asking the question may have very legitimate reasons for doing things they way they do it, reasons you couldn’t possibly know when you haven’t seen the project in its entirety. Sometimes the only reason for this is that “it would take too much time to change this right now” and this is a perfect valid reason for anyone living with time constraints and having a hard time getting the fundamental concepts right.

We don’t, in that 1/100 case that this is true, I help them find the answer for how to do this the hackish way that will work for them. I then table that hackish way for helping others in the future, and use it to suggest to core new APIs that should be public to make this thing easier to accomplish in the future. We (the people usually answering questions on Slack) just don’t start with the hackish way, because it’s that hackish way that prevents you from easily upgrading ember, or gives you maintenance headaches, or induces bad performance in your app.

Ember’s community is too small for that to happen, at least at the moment.

I don’t think that’s true at all anymore.

If you have a non-standard API, you’re kind of out of luck for example. Yes, there are ways to get it to work, but it’s completely not obvious how to do so and may require substantial reading of the source code.

Absolutely, and I’m working with some others and I’ve been reaching out to ED devs to encourage improvement here, find me on slack (@runspired) and I can point to you some of the ways you can easily throw a layer in front of ED now to make it play nice. We need a few more cowpaths before we can build a good solution that solves edge cases, and it’s likely going to be an addon with an alternated ED interface and an alternate adapter/serializer layer to enable that.

the 20% of the time that you need to do something different, it ranges from extremely painful to near-impossible.

I felt this way in Ember several years ago, but once I learned the primitives a bit more I realized that 99% of that 20% I’d been getting in my own way. While Ember has a lot of areas in which it needs to improve, there aren’t many things that it actually makes painful to near-impossible. This, I think, is where the guides actually fall short. They don’t do a great job explaining concepts that are mid-to-high level.

I’m yet to upgrade to 2.x since I have add-ons that rely on deprecated functionality. I also dread the complete dropping of controllers.

Controllers weren’t dropped in 2.x, you might find this talk useful: https://www.youtube.com/watch?v=zwb3HvjpG3o&index=1&list=PLaKDKbFmAv-aLYGogQ63zzKeUpy_opDia

For starters, there are things in Ember that feel half-baked. For example, how can I create route that has optional route segment, so I could hide page number from url for first page? Having multiple url’s point to single controller was non-issue back in 2006, yet in Ember.js its challenge enough to ruin your day.

This sounds like queryParams for pagination

Getting custom loading templates for “flat” routes, so you can, say, give UI preview for some list, requires nesting your route under “do-nothing” route for Ember to actually use your loading template instead of app’s default one.

All that’s required is for you to properly name the loading route template for that route, you don’t need to change the organization of your route.

Keeping ember-data’s store size under control was always a problem to me, and eventually I’ve developed habit of emptying it completely every time top-level route was entered, so I knew I’ll get up-to-date models from backend, while not using memory for holding some other stuff I’ll wont need beyond that one page.

You’d need to be grabbing a very very large amount of data for this to have been a concern, but you found one of many right ways to do this if you need to.

Eventually my codebase reached size in which broccoli’s build times entered domain of minutes, meaning every time I’ve hit cmd + s in my editor, I was guaranteed enough time to go make myself tea. And don’t get me started about “go buy SSD” as solution.

There’s a lot of common paths that lead to build slow downs.

  • coffee script
  • sass
  • google-material-design
  • no SSD
  • no watchman
  • not turning off your system’s / IDE’s indexing of dist and tmp
  • using an older version of ember-cli

Thankfully, with the most recent release of ember-cli, most of these bottlenecks are gone.

From the looks of it, it seems that Ember is still happy to tell you “calling set on destroyed object” error, like it did back when I was starting with it, which today I’m reading as an part of greater issue:

Well yes, if you’re setting on a destroyed object it means you’re doing something incorrectly that needs to be fixed.

Old API’s are being constantly deprecated for sake of new, “better” apis, that don’t add any value to your project

Perhaps not value that you’ve seen yet, but this sort of churn is common in most frameworks, end especially common in frontend frameworks. Frontend frameworks have to iterate to match changing language abilities and changing browser abilities. This churn also induces developers to find better patterns and primitives to use based on newer / more standardized browser and language abilities. 6 months on the front end is about 3 years in the backend dev cycle. That’s also compounded by most front-end devs being either less-experienced devs (having not spent much time learning anything but front-end tools) or back-end devs unfamiliar with what’s really available or possible on the front-end.

but force you to return and iterate closed parts of your project, sometimes actually taking away features that you relied on, forcing you to hack around.

I’d love to know what you had to hack around, deprecations happen when a clear path to something better is released.

reconsider options and conculde that reimplementing whole thing on something else will take same time it would take to catch up with deprecations,

You don’t have to replace deprecations unless you want to use the next major release. Deprecations aren’t removed until major releases.

  • Iterate over an array of ember-data objects in your controller/component.

You iterate an array however you’d like. for in, for, while, Array.forEach, Array.map, Array.filter, Array.sort. In short, you use the native JS APIs.

  • Make it more obvious how to access the model in the controller/component if needed.

I think templates have gotten sufficiently involved we should add a page to the docs on how components in a route can inter-operate / how blocks and yields work.

  • Explain how to create a screen that uses multiple data elements, especially where 1 isn’t specific to the current route (think of user profile information in a header and then a list of blog posts in the main body. It’s not clear, and no examples show how/where the call to the user profile stuff resides).
import Ember from 'ember';

const {
  inject,
  Route,
  RSVP
} = Ember;

export default Route.extend({
  session: inject.service('session'),

  model(params) {
    return RSVP.hash({
      user: this.get('session.user'),
      foos: this.get('store').find('foo'),
      bar: this.get('store').find('bar', params.id)
    });
  }

});

But I think it’s also a problem that we are only focused on fixing the documentation for the newest versions.

This is necessary, it’s a highly complex and nearly impossible task to fix the docs for older versions. You end up needing commits applied to the docs for N versions, which you must determine the correct range for, it’s not enough to PR a change to one version. If you’re using 1.13.x though, the docs for 2.0 are equally valid if you’re seeking becoming deprecation free.

3 Likes

I haven’t done that, and neither have most people in this thread. Read the thread. Most of the questions raised are illustrative examples, not ones we still need answers to.

We need a place to vent our frustration and criticize without being told we are off topic. If you lock down this thread, I’ll criticize and vent in other places.

Seriously, read what he wrote. He’s well aware that components haven’t been dropped completely (yet) but will be in the future. And seriously, a talk on services as a response? SERIOUSLY?

You might be surprised at how much easier it would be to write and maintain decent documentation if only the framework wouldn’t churn so much.

I’m not some new developer. I wrote my first web page in 1994. I’ve been a web developer for 15 years. I’ve worked as a back end and full stack developer. I’ve been specialized in front end development for the last three years. And now I work in an enterprise on a front end with > 40k LOC. Which I spent MONTHS moving to Ember CLI. And I’m still stuck at work on Ember 1.12 until we can get our dependencies to work with a supposedly compatible minor update.

We don’t want to rewrite our code every year. We are frustrated that we have to update so often. We were promised “stability” and we didn’t get it. We were advertised a framework that would be useful for large, ambitious web applications, and we got one that is only good for small apps because it changes too often. So we vent and complain. How do we get listened to?

6 Likes

I found Ember pretty easy to learn too. But, I wasn’t burdened with a lot of front end experience so I could just experiment and do stuff the way that took the least amount of code and leveraged Ember the most. I also think it really helps to be comfortable reading code (the Ember source is great for reading) and the API docs.

1 Like

I don’t feel “complaining” on this topic will do much more than lifting some frustration though. Valid concerns (and I believe most, if not all, are) would probably benefit from getting some structure and, perhaps, a RFC issue or just their own topic here.
Otherwise, I am just feeling some valuable feedback is being lost.

I think this is probably the case. The experienced devs all say “well, you can do anything”, while the newbies (to the framework, not necessarily to development) often throw their hands up in frustration. Assuming the experienced devs are not all liars or blind, this must mean that there is a lot of stuff to Ember that is really, really hard to understand properly. So, the more that can be done to improve documentation (including conceptual documentation, complete tutorials, etc.) the better.

Also keep in mind that many people’s experience with Javascript is “I manage all event handlers myself”. This leads to a lot of trouble when e.g. integrating external plugins etc. It is very important to understand how to let Ember deal with all this stuff properly.

I think it is. There’s still tons of in my opinion important open issues that haven’t been fixed yet. There’s still things missing in the ecosystem. I don’t mean this as a criticism, but to me it is obvious now that if you want something like:

you have to invest a significant amount of your own work. Now, I understand we are using open source software, so I have obviously no right to expect people to do XY. And I don’t. I’m just saying that, when I chose to use Ember, I wasn’t aware of the many pieces that are still missing.

Also, a very bad side effect is that sometimes “fixes” for open issues only get released in the current Ember branch, so whenever you don’t have the latest Ember it is possible that you still have bugs / problems that would be fixed otherwise. Obviously, SemVer doesn’t cover something like that. (For an example, see this bug with Mixin / super, where a fix hasn’t been backported to older Ember versions).

I don’t know what the situation is with AngularJS. I only hear “this is so easy in AngularJS” all the time.

The context in which I wrote that was that @jasonmit wrote “you have to disconnect Ember from Ember Data” (i.e. “if you criticise Ember Data, you are not criticising Ember itself”). To which I replied that this obviously is disingeneous if Ember Data is advertised all over the place.

Also keep in mind where the criticism is coming from. It comes from people saying things like “this is super easy in AngularJS, it’s just POJOs everywhere”. And that is, I think, where we need a very open discussion about:

  • why we have Ember Data at all
  • what problems it tries to solve
  • why you might want to opt out in particular cases (highly non-standard API, incredibly simple project with only two endpoints, or something like that)

etc. If people understand that there is a reason why ED is so incredibly complex, I think this would go a long way.

I think a great example of the struggles that cause people to abandon Ember are shown in posts like this.

It’s a fairly simplistic action, but Ember (or at least the community) doesn’t seem to have a good answer for how to handle this. The downside of opinionated frameworks is that you spend more time having to document, explain, and support those things that fall to the edges of the opinion. The above blog posts references one of them. And it’s a case where routable components aren’t going to help either.

The community does more to address these issues, the more people will stick with Ember.

1 Like

That’s an interesting example, because IMHO, there is a perfectly valid technique for that use case (use a service), but the answer just never surfaced in that thread. Maybe in 2013, which is when the thread was created, this was not so obvious though. Or maybe my view is unorthodox, but I don’t tend to see DDAU as the answer to everything.

I try to use DDAU where otherwise I would have to work with two-way bindings, but for cross-cutting concerns services are perfect. Your components are still decoupled, because you have DI (and you can mock out the service in testing), so I think this is a good solution.

So what’s more interesting about this case is why this has not been accepted as the canonical answer.

1 Like

@Fryie I agree. To me the fact that this common scenario isn’t clearly addressed in any guides or tutorials from the community itself leads to many people (including me) to feel that Ember isn’t really mature enough for me to commit my company to. It’s not that it can’t be solved, or that the services answer isn’t the right one. It’s that the community can’t seem to agree on the answer and provide clear guidance for users.

The rank-and-file users don’t want to have big debates about the right way for the framework to work, the need to know how to navigate the framework so they can deliver the functionality that their org does care about.

To me, Ember just doesn’t feel ready for anyone outside of the “Innovators” group, where Angular (and others) has matured to the point of working with early adopters and even early majority.

Let me briefly talk about this issue. Let’s say I have a frontend dev[1] who adds a component rating. It looks like this:

...
setupRaty: Ember.on('didInsertElement', function() {
  var component = this;

  this.$('.star').raty({
     ...
     click(score) {
       component.set('score', score);
     }
  });
});

Where raty is just one of your run-of-the-mill jQuery plugins. It is entirely reasonable for a frontend dev - or actually any dev who’s not entirely familiar with Ember - to write code like this. This is a huge conceptual gap in documentation etc. It is not at all obvious that if you use Ember you cannot continue just attaching event handlers like you used to. For you (and me now) it is clear that you need

  1. to remove the event handler on willDestroyElement
  2. to check whether the element is actually still present on the page inside the click handler by checking for isDestroyed etc.
  3. You also will want to wrap the whole event handling logic in a run loop but you won’t notice until your tests start complaining

I think this is where the calling set on destroyed element complaint comes from. Newbies write code that makes total sense to them and then they run into weird issues that they do not understand. Additionally, IIRC, the stack trace for this error is next to useless. Furthermore I wonder why Ember does not automatically check for isDestroyed etc. before setting; you could argue that explicit failures are better than silent ones but we’re talking about a framework that happily will let you retrieve this.get('foo.bar.baz.quux') even if not a single property in that chain exists. FWIW, I have the following util now:

export function elementPresent(element) {
  return !!element && !element.get('isDestroyed') && !element.get('isDestroying');
}

I apologise if I have mischaracterised the situation as it purely reflects my current understanding.

This is btw not to say that is an issue for me atm, it’s not. But I understand where the complaint is coming from.

[1] by frontend dev I mean somebody who specializes more in CSS, animations, etc. than in business logic, API communication etc.

It’s really not a common scenario.

This is no different than in any code you wrote before Ember, what I think you’re really getting at is that in the past frontend devs were taught they could be lazy and were never asked to understand what they were doing because you could ignore consequences of your code by assuming it would all be thrown away when the user navigated to the next page.

I can’t begin to explain how many things I debug from jQuery days where a plugin never cleans up after itself, or even non-jquery libs (like html-gl) that just assume a setup-never-teardown mentality.

You really don’t need to check isDestroyed in your example, if you tore down the handler correctly it would never trigger on a destroyed component or view.

How so? Are you saying that cross-cutting concerns are not “a common scenario”? We have lots of different places where the same behaviour can be triggered in our application. I’m not sure this is so uncommon. It’s certainly not uncommon for a traditional non-SPA page.

[quote] This is no different than in any code you wrote before Ember, what I think you’re really getting at is that in the past frontend devs were taught they could be lazy and were never asked to understand what they were doing because you could ignore consequences of your code by assuming it would all be thrown away when the user navigated to the next page.[/quote] That’s fair, and that it isn’t Ember’s fault that devs or plugins don’t clean after themselves should also be clear. I just wanted to point out that:

  1. This attitude to JS development is still the card we’re dealt with, so the more can be done to explain what is wrong with it and how you do things properly, the easier it will be for people to pick up Ember. Many of the people who come to Ember are not necessarily newbies to programming in general, just to JavaScript, and the limited exposure to JS they might have had is exactly that kind of cowboy coder style. I haven’t compared whether Angular or React address this problem in their guides or not, so it’s possible this is just a general problem with serious JS development.
  2. However, the area where Ember could be giving some more help with this would be 1) better error messages in such a case, or 2) alternatively “silently” swallow this error. This is arguable, of course, it’s about fail fast vs. recover everything. It’s also more consistent with what you would expect from the JS programming model in general - there things just either are in scope / referenced somewhere or not. The situation that you can access an object but it is “destroyed” is unusual, at least; and finally 3) just very explicit documentation about this behaviour. Once you know it, you’re less likely to run into that problem, and if you do, you’ll know what’s probably caused it. That said, I remember being completely bewildered the first time I read that error message.

That’s what you’d think and would make sense, but in the case I had, I really needed to check for the element presence; I can’t tell you why, though. Maybe the plugin did something weird.

It’s not the only case though. Here’s another example:

  animate: Ember.observer('value', function() {
    this.set('valueOld', this.get('valueNew'));
    this.set('valueNew', this.get('value'));

    if(this.get('valueOld') > this.get('valueNew')) {
      this.set('animationClass', 'is-sliding-down');
    } else {
      this.set('animationClass', 'is-sliding-up');
    }

    var self = this;
    Ember.run.later((function() {
      // this could have been destroyed by now
      if (elementPresent(self)) {
        self.set('valueOld', self.get('valueNew'));
        self.set('animationClass', '');
      }
    }), 400);
  })

Now, the way this code is written probably not the best way - but still, the issue (as far as I understand it), is that you schedule some properties to be changed only after a certain timeout, but after that you might have navigated away from the route so the component could have been destroyed. I think, in this case you need the manual check, and at the very least it would be nice for Ember to provide a built-in function for it (and explain the component lifecycle a little bit more in depth).


I hope you don’t take this the wrong way, @jthoburn. I’m more productive with Ember every day (even though there are still issues I sometimes struggle with), but I went through a lot of pain and I would just like to provide my perspective in order to maybe eventually help keeping other people from going through the same pain. I’m not experienced at all with Ember (or JS development, or any kind of event-based development actually), so the actual contributions in terms of RFCs, proposals, etc., I can make is limited. I understand that this thread can be seen as just nitpicking and complaining, and that this might drive people away. It is, ultimately, an issue of how, when and what to communicate, and it’s not always easy to figure out the best way.

1 Like

This case would also be about cleanup. Ember.run.later returns a timer number, which can and should be used to cancel the the scheduled function.

animate: Ember.observer('value', function () {
    …
    Ember.run.cancel(this._animation);
    this._animation = Ember.run.later(…);
}),
destroy: function () {
    Ember.run.cancel(this._animation);
    this._super();
}

You do have a point about error messages being sometimes difficult to use, especially when things are run asynchonously. The two main culprits being glimmer and backburner. I found that providing an explicit name for all my async functions helped a lot when debugging (Ember.run.later(function animateFoo() {...), because they will show up in chromium/firefox stacktrace.

The error you get when setting stuff on a destroyed object is actually a feature. You could just remove the assert from Ember’s code and it would work perfectly… except you just removed the easiest way to debug memory leaks.

Checking for isDestroyed is not a good approach either. It just circumvents the bug-detection feature. So it just hides the fact that the handler is still registered after it should have been torn down, remaining there as an obvious memory leak. You are removing the warning instead of fixing the problem.

Basically, this error is a “check engine” light. Silently swallowing it would be akin to removing the light. The checking for isDestroyed is akin to sticking rubber tape on it so as not to see it. It’s true developers used not to care about the engine breaking down as on traditional JS apps, you would throw away the car for a new one so often it did not matter. Now, one-page JS apps are going long-haul, so engine health does matter, engine manufacturers must put the light and developers must start to care.

1 Like