Calling a route action from a component fails

Hi,

Contrary to what the doc that your link pointed to says, and this snippet from an Ember book:

sendAction(‘onClick’, …) sends the action name passed in to the component (updateRating in the above case) with some optional parameters. That action will be handled by the first handler on the “controller, then current route, then active routes” path. In our case, the bands.band.songs route will have the privilege to do so.

It looks like the action must be defined in the controller, not the route.

For example, I have a component and added the following anAction param to to the way I called it:

{{users/settings-form user=model
                  selectedState=(user/select-state model)
                  anAction=(action 'myAction')
                  onSubmit=(action 'register')}}

Then I called it from my component, thusly:

  this.sendAction('anAction');

When I put the myAction handler in the controller it works fine:

    myAction() { alert('got it'); },

However, when I remove that action from the controller and put it in the route, my app doesn’t even display the page due to the following error:

Error: Assertion Failed: An action named 'myAction' was not found in <bnc@controller:users/register::ember487>

I have been burned on this before, and have found it confusing as to what the rules actually are for calling actions from components.

For example, there was a long discussion in here (Where should I define a `save` action? - #2 by tristanpendergr) about this very issue. People went back and forth about whether or not the action(s) should be defined in the controller or the route… but that discussion struck me as moot when dealing with components, because in that case it seems that the only option is to put the action in the controller.

Also, it seems to me that sendAction is kinda sorta deprecated in favor of closure actions. From that same book:

From Ember 1.13 onward, there is another way to trigger actions. Instead of passing in an action name (a string) to the component, a function, returned by a call to the action helper can be passed in.

And here is the example he gives, with the old string way and the new closure action way:

{{star-rating item=song rating=song.rating onClick="updateRating"}}

{{star-rating item=song rating=song.rating on-click=(action "updateRating")}}

In this (closure) way, he points out that the action must live in the controller:

The action helper looks up the provided name in the actions object of the current context, in this case the controller and creates an action function from it encapsulating the current context (hence the name, “closure action”).

I’m just starting out, so I’d love to hear what someone more knowledgeable than I has to say on this subject.