9 ms·
Ember.js is driving me crazy
- kaonashi 13y agoConvention over configuration achieved with opaque magic can actually harm the dev process more than it helps.
- alipang 13y agoHaskell: favor composition over configuration over convention.
- kaonashi 13y agoIt works well for JS, too. Favor function composition & higher order functions for code reuse over complicated prototype hierarchies.
- platz 13y agofunction composition in js can be tricky to visually parse the "types" (especially if curried).
- kaonashi 13y agoIt depends on the return value, yes. I usually try to keep modules small and use some kind of threading (needle + thread analogy, not os threads/web workers) strategy when building functions -- pulling out common patterns into globally visible utility functions that work with common types (e.g. jQuery events/objects). It's not ideal, but in the absence of a true type system, it's all about mitigating potential problem areas.
- badman_ting 13y agoYeah, it kicks your ass when you're just getting started and helps you move somewhat quicker once you have experience. But I have observed what you point out many times. I'm not sure it's worth it, in the end. You learn how to Google error messages, that's for sure.
- jonnii 13y agoI write a lot of ember. It can, occasionally, be frustrating (for example run loop craziness), but in my opinion it's no more frustrating than working with any other stateful front end framework (WPF, backbone etc...).
- kaonashi 13y agoI've done quite a bit of Ember as well, and lately I'm kind of liking React's approach much better. It composes well with many routing/model solutions, and keeps the 'run loop' isolated in the view layer.
- CookWithMe 13y agoScala dev here who sometimes needs to do some JS (though haven't worked with ember). I feel your pain! Static typing and functional programming certainly make ones life easier once a project becomes bigger. Anyway, for future reference, you may want to learn how to use the JS debugger (both Chrome and Firefox are quite good). You could have set a break/watchpoint on the variable 'foo'. Once it has changed, you can inspect the stack and would have found that the set('bar', ...) method was involved. Should be much quicker than printf-debugging...
- mightybyte 13y agoI use the debugger all the time. One problem is that when you're using Ember a lot of the call stack is cluttered with Ember internal calls, which obscures things. But even after I isolated the problem down to that line, the debugger still didn't help me fix the problem.
- CookWithMe 13y ago> a lot of the call stack is cluttered with Ember internal calls, which obscures things. Your debugger should be able to display the corresponding .js file for each line in the call stack. Jump down the stack until you find your code. Yes, it doesn't solve the problem (wanna talk about debugging freaking JSP or TinyMCE plugins? :p) but you won't > spent the better part of a day trying to track down the source of this problem.
- astrodust 13y agoThe Ember Chrome Extension (https://chrome.google.com/webstore/detail/ember-inspector/bmdblncegkenkacieihfhpjfppoconhi?hl=en https://chrome.google.com/webstore/detail/ember-inspector/bm...) helps a lot.
- thatthatis 13y agoI seem to remember reading that chrome added the ability to "black box" libraries to remove them from the debugging call stack to help with situations just like this.
- al2o3cr 13y ago" but at some point I decided that the widget was no longer needed, so I commented out the widget's markup" SOURCE CONTROL, DO YOU SPEAK IT? In all seriousness, this is a major peeve of mine - the time that you're most confident that code can be deleted is when you're removing the pieces that depend on it. If the deletion really turns out to be wrong, you should be able to restore the code from source control. If you can't, stop using broken source control. Leaving leftover dreck in your source files "just in case" is like stashing your leftover sandwich crumbs in your pocket at lunch. Clean up your mess!
- astrodust 13y agoExactly. If you're committing large sections of code that are commented out you're doing it wrong.
- oinksoft 13y agoThe mental effort required to find and pull the old code is far greater than that required to toggle a code comment, or just the line using that code. The author rightly points out bad behavior by Ember: Unused code should not affect program behavior.
- ef4 13y agoBut that's a one-time mental cost. There's also the mental cost of navigating among all that commented code every single time you need to read that piece of source.
- Kequc 13y agoYes code should be deleted and then later recovered from source control. In the event it is needed to be glanced at or restored, but you're exaggerating how problematic commenting a method out of code is. If I'm scrolling through code and see a commented out method my brain says "well that's not in use" and I move forward. If a commented method stays in code for a few months I would complain or simply remove it myself, but it isn't hurting anything (unless in the case of Ember).
- samspot 13y ago> The root of the problem is the system we were operating in: an impure programming language with weak dynamic typing. Is it really fair to blame this on dynamic typing? Having setters with side effects seems like a design decision to me, and not one that is easily supported. I would be interested in hearing an explanation of why this behavior is javascript's fault.
- mightybyte 13y agoI'm not blaming it definitively on dynamic typing. I'm blaming it on the overall system of incentives that I have observed seem to come up a lot more frequently with impurity and dynamic and/or weak typing.
- DasIch 13y agoIn a pure programming language with strong static typing this effect would simply be impossible to produce in a way that wouldn't make the problem obvious.
- michaldudek 13y agoShould have gone with Angular :P
- ef4 13y agoThe things that are frustrating about writing an Ember app are the things that are frustrating about Javascript in general. Those "set" and "get" calls are a great example: they're an unfortunately necessary workaround for Javascript's lack of real dynamic message dispatching (like Ruby's method_missing). We all look forward to ES6 fixing this. The run loop is another example. It's a gross hack that wouldn't be necessary in a nicer language that managed its own runloop internally. Javascript developers who are ignorant of other paradigms often make the false claim that all the callback-driven asynchronicity is worth it because of performance, but they fail to realize that you can have exactly the same asynchronous architecture while writing code that reads synchronously.
- strager 13y agoI don't see how this relates to the problems posted in the article. How does the lack of Proxy make the behaviour less confusing? Where does the author mention asynchronous behaviour and JavaScript's run loop?
- ef4 13y agoI was just commiserating and sharing my own experience. The problems posted in the article are really hard to judge because the author doesn't actually explain what happened. In the first example, he doesn't try. Fair enough, it's a judgement call on whether to spend time understanding what happened. Personally, I would consider it high priority, because otherwise you have no assurance that the same problem isn't biting you elsewhere. In the second, he says something that doesn't actually make sense: "Ember's set function has special behavior for values in the content field". I know Ember's source about as a well as anybody not in the core team, and that statement isn't even false. If I had to guess, I'd assume he's really saying something about how ObjectControllers behave as proxies for models. I don't mean to write off whatever problems he encoutered -- they are clearly real problems, either bugs in Ember or failures of developer ergonomics. If he could point to the specific actual problems I would personally work on a patch to address them. But I don't have enough to go on.
- 13y ago
- jessep 13y agoI attempted to use Ember in side projects for quite a while, really dove in. Sadly, I never got productive with it. My conclusion was that Ember works for super smart people with a background in traditional MVC UI architecture (different than MVC server architecture), but that mortals like myself probably aren't up to the task. I moved from Ember to React, and it has been a joy. It does what I actually want: makes interfaces easier to develop, lets you build your interface by composing parts together, lets you write view functions that are as smart as you are (no crippled templates like Ember/Ng). It is basically a simple low level building block that makes a lot of other stuff easier. Anyway, as a non-genius developer who nonetheless has written a lot of javascript, React is my strong preference. Their approach is beautiful and simple.
- thatthatis 13y agoWhat do you use for routing and models with react?
- jessep 13y agoI haven't handled routing yet, a lot of people seem to use https://github.com/flatiron/director https://github.com/flatiron/director, which I would probably do. This is the one area where I missed something from Ember. For models, I've just rolled my own so far. I've experimented in one small project with having a global state object that cotnains all application state data, and then just having domain fns that operate on that data. Inspired by the react people's descriptions of "flux" architecture. It felt really nice. When using Ember, I got really confused by Ember's Ember Data vs. Ember Model vs. whatever conversation. Again, I just didn't really know what to do here, and I attribute it to my own shortcomings.
- machty 13y agoIt might not be so much a genius vs non-genius thing so much as your particular app not needing the heavyweight app-state management that Ember provides. It's worth pointing out that the Ember core team has been approached by the React core team with the intent of unifying React's view layer with Ember's application state management, which is a major component of what Ember offers relative to other frameworks. If you haven't had to solve major problems with navigation, routing, complex nested async logic, etc., for the particular app you're trying to build, then it sounds like React would get you most of the way there, but even the React team themselves realize that for medium-large scale apps, React's only going to take you so far.
- mdemare 13y agoThe author mentions "The Fifth Discipline" a couple of times. Has anyone read it? Worth reading?
- Touche 13y agoEmber is just too magical. Handlebars alone is larger than a lot of competing MVC frameworks. Avoid.
- sequence7 13y agoOK, so that's a very link baity way of saying. I don't know JavaScript or how to use source control and when I come across unexpected behaviour in my code I don't take the time to understand the cause. JavaScript is hard, it's a very loose language and it's implementation in browsers sets you up for all sorts of falls. If you're going to code using it you either need to be disciplined or understand it intimately, preferably both. The problems in the article were not caused by Ember.js
- orochi235 13y agoI'm an experienced web developer (Backbone is my preferred framework) whose team is migrating to Ember. It has its high points, but on the whole, it's been driving me nuts. Ember, like most modern frameworks, represents itself as MVC. But it's more like MVCLCTMRA (model-view-controller-layout-component-template-mixin-router-application, if you're following along at home). There are just so many moving pieces, and there's a lot of overlap between them. Should I be using a layout, a view or a component here? They're ALMOST the same, and they don't always vary in the places you'd expect them to. Also, the "model" portion, ember-data, is fairly immature and doesn't seem to be anywhere near production-ready. There are also some design decisions that just leave me baffled. If templates are supposed to be the ideal place to declare stuff, why does a view's root element have to be declared in a bunch of JavaScript properties instead? Why do some of their camel-case names (e.g. RESTAdapter) violate the (fairly strict) naming conventions they enforce in user land? I don't hate Ember, and I'm sure it perfectly fits the mental schema of at least one person on the planet, but it doesn't click all that well for me. And it's abstract enough that I don't think working through problems in it is making me better at anything except Ember. It's also probably worth mentioning that about 80% of the documentation online seems to be in the form of StackExchange posts, and about 80% of those are obsolete, as Ember has gone through a lot of radical changes in the not-too-distant past.
- MatthewPhillips 13y agoIf you're experienced with Backbone but want something that competes with Angular/Ember in terms of features, you should really try CanJS[1]. It has a small API surface area so it's very easy to learn but still manages to bring advanced features like Web Components to the table. [1]http://canjs.com/ http://canjs.com/
- rxcfc 13y agoSorry to hear that you've been having trouble with Ember. Let me see if I can answer a few questions. 1) Layouts vs. Views vs. Components A good place to start on this is the guides: http://emberjs.com/guides/views/adding-layouts-to-views/ http://emberjs.com/guides/views/adding-layouts-to-views/ http://emberjs.com/guides/views/ http://emberjs.com/guides/views/ http://emberjs.com/guides/components/ http://emberjs.com/guides/components/ From reading those, it should be pretty clear how layouts differ. I admit that it may be a bit less clear how views and components differ. Components are actually a more isolated type of view. Views have been around for longer, but in the future, we're going to discourage people creating custom view classes in favor of using components primarily. If you're not sure whether to use a view or a component, go with a component first. 2) Ember Data Ember Data isn't a part of Ember Core, and for a good reason. While Ember Data is certainly a useable product (myself and many other do use it in production), it's not yet as mature as Ember Core (hence still being in beta). If Ember Data isn't good for you yet, you don't need to use it. Discourse is an example of a large Ember app that completely forgoes Ember Data. 3) Templates and Views The template is rendered inside of the view's element which explains this. Alternatively, specify `tagName` as a property when using `{{view}}` or a component helper. 4) Documentation The guides have a ton of information so you should definitely look there first. Also, if your company is really investing in Ember there are some good paid trainings available, including online courses. Tilde, my employer, has an online training (http://www.tilde.io/events/introduction-to-ember-online/ http://www.tilde.io/events/introduction-to-ember-online/) as does CodeSchool (who I do not work for) (https://www.codeschool.com/courses/warming-up-with-emberjs https://www.codeschool.com/courses/warming-up-with-emberjs), among others. Since Ember has reached 1.0 a number of months ago, the API has stabilized and documentation will be valid for much longer.
- jonny_eh 13y agoI'm not sure why the author blames JavaScript for deficiencies in Ember. He wouldn't have encountered the stated problems with Angular, I bet.
- Glyptodon 13y agoOkay, so you had a problem with Ember. But the whole leap to needing "strong static type system like Haskell" leap seems really random. It seems more like a need to spend more time with JS (which can be weird and a pain, but eventually makes sense) than blame Ember, which is pretty complex on top of the various aspects of JS that are a bit unintuitive to start with.
- shubb 13y agoI think this is the culture shock of not working with a compiled language. I mostly work in compiled, statically typed languages, and it can be a bit of a surprise in Javascript when you don't find out about a syntax error until execution just stops, half way through your application loading, because of some code in a function you didn't think was called. It's a surprise. But that doesn't mean it's wrong. We just aren't using the right tools - unit tests, JSLint, etc. Question to regular JS users - what do you do 'in place' of static checking?
- kevincennis 13y agoJSHint is helpful, especially (I think) for people who don't write a ton of JS. Unit tests are obviously important. I've been using Istanbul lately to check my test coverage, and that's made a big difference. It's awesome to be able to see, quickly, that "Oh. I'm not even testing half of this function." Sticking to some kind of style guide also helps. Idiomatic.js is a good starting point. Also, doing some basic checking on your own is often a good idea. Look at your arguments, make sure they're what you expect, and if now, throw an error. That'll make it a bit easier to see where your problems are, since you won't have to dig around stack traces as much.
- oinksoft 13y agoSome people use type-checking compilers like the Google Closure Compiler or Microsoft's TypeScript to perform static analysis.
- MatthewPhillips 13y agojshint is static checking. It would have caught your syntax errors. Even catches when you do something stupid like define a new function inside of a for loop. As far as type checking, typically it's not needed and can be confined in functions that care about types, you just defensively cast to the type you need. Closure's also an option if you really make heavy use of types of your application.
- twerquie 13y agoGenerally speaking, in dynamically typed languages, unit tests are the replacement for compile-time type checking. Type safety should not be a goal, duck typing is embraced and the correct behaviour is verified.
- ulisesrmzroche 13y agoRemember to use Handlebar comments in your templates, instead of regular html comments.
- ianbicking 13y agoHe points back to static typing, but honestly I think UI code is harder to keep organized than service code (which I presume is what the Haskell backend does). Usually it's the UI that has to swallow the biggest chunk of the mismatch between the programming model and the user model – and as you move to smarter clients like you would with Ember.js, you end up pushing nearly all of that to the client. And you have to start interfacing with substantial complicated pieces of code, like the browser, code that every UI has to not just use, but negotiate with. All this complexity can be a way of coping with this system – not just coping with the system of a dynamically typed language, but all the many conflicting constraints in a browser environment implementing a UI for real people. That said, there are differing opinions on which part you should "simplify" through a framework. Some of them are going to feel more magical than others. And when you come in with preconceptions about what makes a good environment, you're going to think about how the framework and environment lives up to your ideal. Some things you fix, some you leave as they are – and choosing the right battles is incredibly important. But service code and UI code are different sorts of warfare against complexity, I'd be skeptical of intuitions across the two domains. (None of which means Ember.js gets it right either – but if they don't, then I doubt the why is they just need a statically typed language.)
- mightybyte 13y agoI've actually wondered some of this myself. I think the answer is that it's some combination of both inherent complexity in UI code AND problems that you get with weak and/or dynamic languages. In any case, we're probably going to switch all of our front-end code to Haskell, so I should be able to make a comparison at some point in the future.
- rxcfc 13y agoI understand the frustration of the author, but it's hard to tell exactly what the source of his issues is. Not enough information is provided in his descriptions to actually understand what is going on. I suspect that either he has run into a bug (which of course should be fixed) or that he's misunderstanding the behavior. It's very possible that he was given some bad explanations for the behavior which has further confused him. I've reached out to him to see if I can get some more insight into the details of the issues.
- ufo 13y agoCan anyone who is more experienced with ember help explain what was going on in those two weird examples in the OP? (Commenting a widget affecting another one and setting the "bar" field also changing the value of "foo" field)
- tomdale 13y agoIn this case, the author didn't actually comment out the code; he left it in place, assuming it would not affect the app when in fact it did.
- rxcfc 13y agoIn the first case, he was using an `ObjectController` without understanding the special behavior of the `model`/`content` property. In the second case, he used HTML comments to comment out Handlebars code, not realizing that he should have used Handlebars comments.
- mightybyte 13y agoTo be fair, the documentation I was linked to doesn't say anything about the 'content' property behaving this way. It only mentions 'model'. In the second case, it seems quite reasonable to assume it knows about HTML comments and that they would behave as I expect.
- adamferguson 13y agoThe docs for ObjectController (and ObjectProxy, which ObjectController extends) both mention the specific behavior about 'content' (not model, the fact that model and content mean the same thing when you're talking about proxying controllers is something you learn as you go along): http://emberjs.com/api/classes/Ember.ObjectController.html http://emberjs.com/api/classes/Ember.ObjectController.html http://emberjs.com/api/classes/Ember.ObjectProxy.html http://emberjs.com/api/classes/Ember.ObjectProxy.html Sorry to hear about the pain points so far. I felt like this many times when I was starting with Ember. It definitely gets better the more you become familiar with all the different conventions.
- deleted 13y ago[deleted]
- nathanhammond 13y agoZombie Code Apocalypse: I would love to help you identify what it is that caused that problem. I don't suspect that it is an issue with Ember itself, though note that the Ember resolver will load code when you store it in `App.Foo(Controller|View|Route|...)` if that code is "needed" (say, by visiting the Foo route). So, unless you commented out the entire declaration it is entirely possible for that code to execute. Spontaneously Changing Values: What was the key that you were trying to set? On what type of object (Route, View, Controller, etc.)? There are indeed some special values and it might be something that Ember can warn you of in the console as well as be documented. I'll be glad to make some documentation changes that make this issue easier to catch if you can provide me reproduction. Godlike Refactoring: I work on a team with a widely distributed level of skills. One of my favorite features of Ember (which both has and will continue to save me hundreds of hours) is the fact that even if you make a mess of something you can generally come back and clean it up one piece at a time. My metaphorical description of this is that "all of the crap is in nice neat little piles instead of spread on the walls." JavaScript.next: In the next/current version of JS both of these warts should be possible to resolve using Modules and Object.defineProperties(). I firmly believe that your complaints are not centered around Ember (which I honestly believe is insulating you from the worst of it) but instead from flaws in a language that was literally designed and built in an incredibly short time (my recollection is "a week" but I can't find a source). (Edited for clarity based upon mixonic's reply.)
- mightybyte 13y agoI posted a comment on my blog with more information.
- mixonic 13y agoJust a nit for accuracy, but the implication that "the Ember resolver will load code when you store it in App.Foo(Controller|View|Route|...)`" eagerly is not true. I believe the author use an HTML comment to comment out his usage and not a handlebars comment, so the code was still being run (just hidden behind html comments). But regardless, Ember will not load everything in the App. namespace blindly- it will wait until that item is required, then try to load it. This is your helpful Ember #protip for the day. :-p
- Skoofoo 13y agoThe issue is that JavaScript is being given a larger load to carry than it was designed to hold. We need to upgrade to using Ruby with Meteor-esque frameworks, and fast.
- ekanna 13y agoI have tried ember and angular. And finally settled with ractivejs.org
- ebryn 13y agoHey, I'm Erik, an Ember.js core team member. I'd be happy to help you track down the issues you came across and explain to you what is going on. You can reach out on Freenode or Twitter, I'm @ebryn. Otherwise, email me at erik.bryn -at- gmail.
- marknutter 13y agoI've worked on large javascript applications written in Ember, Angular, JavsacriptMVC (now can.js), and jQuery and the conclusion I've come to is that things have not settled down in the world of front-end development enough to justify a framework as opinionated as Ember. For example, Ember relies very much on routing being handled a certain way. In fact, much of the magic in Ember comes from the fact that it's making a lot of assumptions about how routes are handled, constructed, and organized. This is great if you can assume that an app's routes will be written in a very traditional way, aka one route per page. It breaks down however when you want to tie different routes to two or more components on the same page (i.e. two different tabbed sections). One concern per route makes perfect sense on the server when serving a traditional stateful web application but it often doesn't make sense for rich desktop-style applications (which is probably why Photoshop doesn't have urls). Data persistence on the client is another area I feel hasn't been nailed down in general and thus can't support a lot of opinionated assumptions. Should data be persisted at all? Ember caches data from all requests to the server in a "store", but it's not clear how you keep that cache up-to-date. Perhaps you could use websockets to keep resources current but at the time I was using Ember there wasn't a clear, well supported way to do that. I think the jury is still out on whether we should be duplicating our schema on the front-end at all but Ember-Data has gone all-in on mimicking ActiveRecord. Again, the dust has not settled in a lot of areas of the front-end development world as far as I'm concerned so I don't feel comfortable with these decisions being made for me. I tend to lean toward convention over configuration. On the server I'm a big Rails fan but I feel like it's solving problems that aren't moving targets. On the front end I prefer Angular because it solves the main headaches (two-way binding, testability, modularity) of front-end development without being too opinionated about the stuff we haven't reached consensus on.
- rxcfc 13y agoI'm confused. Are you proposing that web apps don't use URLs? If so, this seems pretty antithetical to the very nature of the web. One of the things that often aggravates people about web apps is that the back (and refresh) button is often broken because of a disregard for URLs. You can see Tom Dale give a defense of URLs here http://2013.jsconf.eu/speakers/tom-dale-stop-breaking-the-web.html http://2013.jsconf.eu/speakers/tom-dale-stop-breaking-the-we.... As far as Ember Data goes, this is something that it's clear that a lot of people do indeed want. That said, you can use Ember perfectly well without Ember Data (see Discourse for example). It's funny that you point to Rails as an example of consensus, because when you look at the server-side development community as a whole, there is certainly not consensus that the Rails way is correct. I wouldn't expect complete consensus on the client side any more than I would expect complete consensus on the server side. Rails (and others) have shown that you can have multiple healthy ecosystems each with their own points of consensus.
- coldcode 13y agoAt some point every programming technology of any power will drive you nuts. If it was so simple a non-programmer could do it, we would all be flipping burgers.
- voidr 13y agoMost of the author's issues could have been replicated in any static typing language, apparently the author is just angry and wants to blame something other then the developers of the framework that confused him in the first place. Also the whole static typing reasoning is BS, because the author could have simply used either Google Closure Compiler Linter that can enforce typehints, TypeScript or Dart.