Sending action from current controller to current route


#1

I am a little confused why this does not seem to be possible:

I have an index controller:

export default Ember.ObjectController.extend({
  needs: ['login'],

  observeSession: function() {
    this.send("sessionChanged");
  }.observes("controllers.login.authenticated"),
});

So, in case the login controller’s authenticated property changes, I would like to reload the index route, as the model of that route changes when the user is authenticated. So I am doing this in the index route:

  actions: {
    sessionChanged: function() {
      this.refresh();
    },
  }

Which leads to the following error:

Error: Nothing handled the action 'sessionChanged'. If you did handle the action, this error can be caused by returning true from an action handler in a controller, causing the action to bubble.

Not what I expected… Now, if I put that same action handler inside the application route, it is called as it should.

Why can’t we send an action from the current controller to the current route?

What is the right way to do something like this?


#2

I would suggest that any action that calls a method that affects routing (transitionTo, refresh, etc) be kept in the route itself. You can call it from the controller and it will bubble up to its router. As I understand it, this is better architecturally speaking. You can make your router do things from the the controller like you are speaking, but it probably isnt the best in the long run.

Here is a link to the diagram on the action helper’s bubbling: http://emberjs.com/images/template-guide/action-bubbling.png

And lastly, the API documentation on the action handler

I’m rather noobish but I hope this helped.


#3

The only thing I can think about: are you sure your actually inside the indexController or the indexRoute ?

If you use chrome for develop, try the Ember inspector extension it. It is really useful in this cases…


#4

When trigger fires it is enumerating over currentHandlerInfos which contains all of the current route objects and params. When your observer fires, it’s firing before the route you’re trying to event to is activated.

trigger: function(name) {
        var args = slice.call(arguments);
        trigger(this, this.currentHandlerInfos, false, args); // <--
}

The only thing I could think of is to defer the observer until the next run loop. http://jsfiddle.net/NQKvy/1229/

Interested to see if anyone else has a solution.

cc @machty mr. router


#5

Awesome. Thanks… That exactly has been my problem and your solution works fine so far.


#6

Hi @jasonmit, I too having the same requirement and is the next run loop a suggested workaround ??