3
votes

I converted this Ember Rails app https://github.com/kagemusha/ember-rails-devise-demo from coffeescript to javascript. The login and registration actions in the AuthController work perfectly when I click the links, however, when I click the logout button, I'm getting an error that nothing handled the logout event, even though there's an action setup to do it in the same controller as the other two links.

Uncaught Error: Nothing handled the event 'logout'. 

        {{view App.MenuItem href="#/login" label="Login" }}
        {{view App.MenuItem href="#/registration" label="Register"}}
         <button class="btn" {{action logout}}>Logout</button>

Can you see why the logout action in the AuthController might not be handling the event. It works in the coffeescript version.

Update, there is a App.NavbarController that extends the ObjectController and wraps the logout in an action hash.

Navbar Controller

  App.NavbarController = Ember.ObjectController.extend({
    needs: ['auth'],
    isAuthenticated: Em.computed.alias("controllers.auth.isAuthenticated"),
    actions: {
      logout: function() {   
        return this.get("controllers.auth").logout();
      }
    }
  });

Authentication controller

App.AuthController = Ember.ObjectController.extend({
    currentUser: null,
    isAuthenticated: Em.computed.notEmpty("currentUser.email"),
    login: function(route) {
      var me;
      me = this;
      return $.ajax({
        url: App.urls.login,
        type: "POST",
        data: {
          "user[email]": route.currentModel.email,
          "user[password]": route.currentModel.password
        },
        success: function(data) {
          log.log("Login Msg " + data.user.dummy_msg);
          me.set('currentUser', data.user);
          return route.transitionTo('home');
        },
        error: function(jqXHR, textStatus, errorThrown) {
          if (jqXHR.status === 401) {
            return route.controllerFor('login').set("errorMsg", "That email/password combo didn't work.  Please try again");
          } else if (jqXHR.status === 406) {
            return route.controllerFor('login').set("errorMsg", "Request not acceptable (406):  make sure Devise responds to JSON.");
          } else {
            return p("Login Error: " + jqXHR.status + " | " + errorThrown);
          }
        }
      });
    },
    register: function(route) {
      var me;
      me = this;
      return $.ajax({
        // url: App.urls.register,
        url: "/users.json",
        type: "POST",
        data: {
          "user[name]": route.currentModel.name,
          "user[email]": route.currentModel.email,
          "user[password]": route.currentModel.password,
          "user[password_confirmation]": route.currentModel.password_confirmation
        },
        success: function(data) {
          me.set('currentUser', data.user);
          return route.transitionTo('home');
        },
        error: function(jqXHR, textStatus, errorThrown) {
          return route.controllerFor('registration').set("errorMsg", "That email/password combo didn't work.  Please try again");
        }
      });
    },
    logout: function() {
      var me;
      console.log("Logging out...");
      me = this;
      return $.ajax({
        url: App.urls.logout,
        type: "DELETE",
        dataType: "json",
        success: function(data, textStatus, jqXHR) {
          $('meta[name="csrf-token"]').attr('content', data['csrf-token']);
          $('meta[name="csrf-param"]').attr('content', data['csrf-param']);
          log.info("Logged out on server");
          me.set('currentUser', null);
          return me.transitionToRoute("home");
        },
        error: function(jqXHR, textStatus, errorThrown) {
          return alert("Error logging out: " + errorThrown);
        }
      });
    }
  });
2
Can you try to use {{action logout target="controller"}}. In the current version of Ember one has to specify them always explicitly, i think.mavilein
There's no need to specify the target unless the target is a view. The default behaviour of the action helper is to call the corresponding controller's action.Simon Cateau
The handlebars markup there is in the template for a 'NavbarView', correct?RhinoWalrus
Are you sure the issue is that the controller is not handling the logout action? It could also be that it is handling it and returning true, causing the action to bubble and then raise the error you are seeing. It's tough to debug this with only the snippets you have provided.Luke Melia

2 Answers

3
votes

Can you show more of your template and views? In the original code the application template uses a render tag to render the NavBar, this renders the NavBar template and starts up the NavBar controller. You might want to throw in an init function with a console log into the controller to make sure its getting created correctly:

init: function(){
    this._super();
    console.log('navbar controller starting...');
}

I noticed that the template code you posted didn't include the {{#if isAuthenticated}} part - is that working correctly?

0
votes

Actions need to be wrapped in an actions object. Check the documentation for more details.