I am facing issue I cannot overcome within the “Error: Nothing handled the action (…) description”. I tried almost everything (changed naming, moved snippet from component to controller, made sure my code is exactly the same as on example and more) but I still cannot trigger simple action by clicking on button.
So from the very beginning: I am newbie in Ember and I am trying to trigger function, which is hooked using {{action}} property.
The template snipped you pasted above should be in the component’s template file NOT the sign-up.hbs, so if that is your sign-up.hbs template you’ll want to either move the template snippet to your component template, or move the action from your component to the route/controller.
Essentially each component has a corresponding template. Components can send actions “to themselves” as it were, or they can call actions that are passed down to them by other parent components, or they can send actions out of themselves to the parent route/controller. If you get a “nothing handled the action” error it usually means you have a template that defines an action, but when it tries to fire the action nothing handles it because the action code is in the wrong spot or named the wrong thing. In this case you want to have an action defined in your component js and that action should be fired from your component template.
Thanks for reply @dknutsen . I actually managed to make it working yesterday by moving snippet from component to controller and it works just fine. Now I see that you also advised to move it to route or controller so since I have a chance I would like to ask you couple of dummy questions because tutorials and documentation are kind of blurry.
First and essential is what is the basic difference between controller and component?
Secondly, does route file contain information about URL handling only or can I store something else there?
Does single template fil include all components and controllers or does it “see” only the one with corresponding name (eg. page.js + page.hbs). Is it possible to use function from different component or controller on different template files?
I will wrap up rest of my questions in simple example. Let’s say I have an application that handles user sign up/sign in proccess. Now, where should I store:
a) Sign up form? (I guess inside hbs file, but what if I would like to run this in a modal window?)
b) Its validation and database insertion? (controller or component or up to me?)
c) Sign in mechanism and its form (same as above)?
d) Sign in/up using facebook module (since it’s just a function that triggers once one click blue button, there is no need to put it in template, but then where to store such action?)?
Thanks you or anyone willing to help for the answers!
So I’ll try and give a high-level outline of the basic Ember concepts and then a bit of history which is highly relevant and then some recommendations. Some of these things don’t really have hard and fast answers but more best practices and rules of thumb.
Now Ember is a complex, batteries-included framework, so there’s a lot to take in at first, but it’s very powerful. It’s also been evolving over the years so some of this is changing as I will describe later. The basic pieces of an Ember app:
Router: module that helps you define your ‘route map’ (router.js) and handles transitions, async data fetching, url and query param related stuff, etc. The router is a big and powerful piece of Ember functionality. This was recently exposed as a service, more on that later
Routes: an Ember “route” is essentially a “view” or “sub-view” in the case of nested routes. Essentially a route has a javascript bit (the route file routes/<routename>.js) and a corresponding template (templates/<routename>.hbs) and (optionally) a controller (controllers/<routename>.js). You can think of the route as the part that fetches async data and handles any transition related stuff.
Template: an hbs file which contains html tags, components, helpers, etc. This is the UI part of your route, where you defined what the route looks like. Templates also correspond to components but we’ll cover that in a second.
Controller: a controller is an optional but (currently) recommended piece of code for handling “view related state” including computed properties that use your model (which was fetched from the route), any state required from the route template (e.g. if you had 3 tabs in the template the controller could keep track of the current tab), and many of your actions. Controllers will eventually be replaced but as of Ember 2.18 they are still recommended for appropriate use cases.
Component: a component is a javascript file and corresponding template that essentially represents a reusable bit of UI. This could be anything from a tiny simple button to a large complex view (that could use sub-components). Components are the best way to reuse UI related code across your app, and they can help organize functionality and separate concerns. The recommended way to use components (you’ll see a lot of references to this) is “Data Down Actions Up” where you send data down to a component from a route/controller and then instead of modifying that data the component sends an action back up to the route/controller to modify the data. That’s a pretty big topic to cover here, and it’s not always the best way, but it’s the general recommendation.
Helpers: helpers are essentially a way to use javascript functions in a template. They can overlap somewhat with components, but I generally use them for “simple things that return a value given one or more arguments”. There are some great addons that include tons of cool helpers like ember-truth-helpers and ember-composable-helpers.
Services: a service is essentially a great way to share “global” data across an ember app. It’s a singleton object that can be injected into routes/controllers/components/helpers/etc. and used throughout, so if you have a use case where the application needs some global state a service is a great solution. For example in our of our apps we have a service for “permissions” that fetches the authenticated users permissions from the server and exposes a couple functions that can be used anywhere in the app to determine whether or not the user has permission to read/write certain resources (so we don’t show edit controls for something without write access for example). Another use case is in the popular ember-simple-auth addon, the authentication state is kept in a service called “session” so any piece of the app can look up authentication state at any time.
Mixins: a way to share bits of reusable js code (like common actions or computed properties). Some people really down on mixins, and they’re certainly not great if you overuse them, but they have some really nice use-cases so I’d say “they can be effective but use sparingly”
Now for a bit of history. Around the advent of Ember 2.0 and React and such the Ember core team decided that the way of the future was components. Controllers would eventually be deprecated and everything would be replaced with components (much like in React). Unfortunately a lot of people jumped on that bandwagon way too soon and so there is a lot of literature saying “don’t use Controllers” and has been for something like 2 years. Anyway, the framework and the component ideas have continued to evolve and we’re getting closer to the point at which “Routeable components” are possible, which will (the way I understand it at least) herald the slow death knell for Controllers (RIP). The first part of this project was exposing the router as a service, and there are several other parts underway as well. It’s unclear exactly when all that will happen though, so in the mean time the recommendation is to use good old fashioned routes, controllers, and components together.
So some of my recommendations and rules of thumb:
Try and handle as much async data fetching as possible in your route model hooks. The router is designed to handle async data fetching and all of the painful headache-inducing complexities that involves. Let it do it’s thing and your life will be a lot easier. This isn’t always possible however, and for cases like those I’d recommend ember-concurrency.
Use your routes properly - as a corollary to the above, make sure you’re using your route the right way. I made a lot of mistakes with this when first learning. So… try to make sure your beforeModel, model, and afterModel hooks all return promises, don’t try and hack weird code into any of those hooks (use them for what they are designed for), use setupcontroller if you want to set anything on the controller besides the model, use the willTransition or didTransition hooks appropriately, etc.
Don’t stop using controllers yet - like I said the framework isn’t yet ready to do away with them. Once it is there will be a migration strategy and I’m guessing it will be something like “convert your routes/controllers to top-level routable components”. For now controllers are the defacto way to do a number of things and can make your life a lot easier.
Use good judgement when abstracting - I personally don’t like to abstract into components too soon. I prefer (with some exceptions of course) to write everything in my controller/template first and then abstract common code or organized units out as needed. Some people would probably roll their eyes or throw up on their keyboard at that. YMMV.
Don’t be too dogmatic about DDAU (data down actions up). Some people would say that a component should ALWAYS follow ddau and never modify data internally and so on. I think that DDAU is a great general-purpose paradigm and makes a lot of sense especially in complex component hierarchies, but if it makes sense in your use case to have a component, say… save a record instead of passing an action up and having the “owner” do it then just have the component do it. Same with data fetching. In general you should leave async data fetching to the router but sometimes it just makes sense to let a component inject the store or make ajax calls (like a quick-search select/search box component). In summary, no rule should be followed 100% of the time, try to think about what makes the most sense.
And… that’s all I’ve got off the top of my head. Obviously feel free to ask any specific questions here or in Stack Overflow or the Slack community. All are great resources for learning. There are lots of other great resources out there too, try checking out some of the EmberConf talks from previous years.
Dear @dknutsen, thank you for the answer, I appreciate time and effort you put to write such a big piece of information. Thanks again, even though it is still blurry for newbie like me yet it is very valuable and I have to study it line by line first before proceeding with my app.
Also, do you know any courses/bootcamps I could enroll to, to learn more about how it all works? You know, manual is just manual. Might be commercial ones as well.
I will certainly recommend EmberMap. A lot of their content is probably for more advanced users but there might be some good stuff in there for a beginner as well. The two guys who started EmberMap are cool and super knowledgeable. I took a training from them at EmberConf last year. Sam is the author of ember-mirage which is a popular and super handy addon for testing.
The Udemy course(s) looks a little questionable in terms of quality, not sure about Code School.
Other than that stuff… I don’t have anything in particular. I’d just hit google for stuff written in the last year or so. And of course use the community resources if you get stuck.