I had started a habit of putting actions in routes instead of the controller, but found that randomly it throws errors in some cases, complaining the action isn’t found in the controller.
I’m not sure why it would fail intermittently. Perhaps the asynchronous routing?
One approach to do this explicitly is set a property on your controller that references the route:
// this is a routing hook that should go in your routes
setupController(controller) {
controller.set('currentRoute', this);
}
From a route’s template, you can then configure the action helper’starget option:
Though this kind of suggestion should be taken with caution. As an aside, I remember reading a chart demonstrating the event flow of actions throughout an application. Something like this would be helpful to better explain what is going on here.
Could it be that the not-found-in-controller errors are coming from calling the action from a component, while the others that are found are being called from a template?
If so, I think components can only reference actions that live in controllers, not routes. Here is a discussion related to that same topic: Calling route action from a component fails
In this case it is not in a component. It is in a template directly belonging to the route. It is a select box change event. Maybe there is something special about this type of event that it has to be in the controller.
certainly is frustrating! I remember seeing a diagram that depicted actions bubbling through an ember application. It seems one could help here to clarify the expected behavior.
Where it doesn’t work, you’re probably using closure actions in which case the referred action is looked up in the context of the template. The context is the controller in case of “route-driven” templates and the component in the case of component templates. Closure actions don’t bubble: if they’re not found in the context of the template, the error you pasted is thrown.
Example of a closure action:
<button onclick={{action "updateRating"}}>
Where it works, you probably use a “string” action, where only a string is passed, like
{{user-form save="saveUser"}}
This is definitely a complicated area in Ember.js, here are a few resources that might help: