Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

401 in application route's model is not caught properly #199

Closed
Myztiq opened this issue Jun 18, 2014 · 8 comments
Closed

401 in application route's model is not caught properly #199

Myztiq opened this issue Jun 18, 2014 · 8 comments
Assignees
Labels
Milestone

Comments

@Myztiq
Copy link

Myztiq commented Jun 18, 2014

I have an application route which has the logic:

  model: (params) ->
    if @get 'session.isAuthenticated'
      @store.find('app')

In the scenario where the fetch of app returns a 401 the authorizationFailed event get's fired but the action never gets called. This is because the listeners are setup in the activate method which is not called until after the model method get's called. One workaround is to define the listeners in the beforeModel call that will trigger the error on the transition parameter passed in. And then on the activate method to turn off those listeners.

My working code that handles this scenario, apologies for the coffeescript.

ApplicationRoute = Ember.Route.extend Ember.SimpleAuth.ApplicationRouteMixin,
  beforeModel: (transition)->
    @_super()
    handlers = {}
    [
      'sessionAuthenticationSucceeded'
      'sessionAuthenticationFailed'
      'sessionInvalidationSucceeded'
      'sessionInvalidationFailed'
      'authorizationFailed'
    ].forEach (event)=>
      handlers[event] = =>
        transition.send event
      @get('session').one event, handlers[event]
    @set '_authHandlers', handlers

  activate: ->
    for event, handler of @get('_authHandlers')
      @get('session').off event, @, handler
    @_super()
@marcoow
Copy link
Member

marcoow commented Jun 22, 2014

Why do you unsubscribe from the session events in the activate method? Will the ApplicationRoute's beforeModel ever be called more than once?

@Myztiq
Copy link
Author

Myztiq commented Jun 22, 2014

Well, the activate will re-subscribe, this is just the monkeypatching I needed to do. So, in beforeModel make sure to subscribe to events and trigger them on the transition object, and then once we are done transitioning, in the activate method we then want to trigger the events on the route itself.

So there would be this flow:

  1. beforeModel: Listen to events and trigger on transition object
  2. activate: Turn off everything setup in 1
  3. activate: Listen to events and trigger on Route

I am not sure if there is a better approach, I dislike the fact that the listeners need to be torn down. It would be useful if we could have it just trigger where it triggers events based on if the transition is complete. Is there a state that we can check for this?

@marcoow
Copy link
Member

marcoow commented Jun 22, 2014

Not sure how to handle this best. The best solution is to have the event -> action translation hooked up in an initializer I think. The idea behind doing this in the mixing is simply that you can "opt-in" into that forwarding of session events to route actions only by including that mixing.

@marcoow
Copy link
Member

marcoow commented Jun 22, 2014

I'm now setting up the event listeners in the mixin's beforeModel. The tests all look good so I think that should fix it. Maybe you can confirm it solves the problems in your scenario.

@Myztiq
Copy link
Author

Myztiq commented Jun 22, 2014

I have not ran the test directly, but while a transition is taking place events cannot be sent on the router itself, they must be sent on the transition object. Let me see if I can hook up a test to show the issue.

@marcoow
Copy link
Member

marcoow commented Jun 22, 2014

That's what I expected as well but surprisingly it worked for me.

@marcoow
Copy link
Member

marcoow commented Jun 23, 2014

Nevermind - it does not work.

@marcoow
Copy link
Member

marcoow commented Jun 23, 2014

I think the best solution would be to somehow use the transition object passed into the beforeModel method which is the initial transition into the app's application route. When that transition has not bee completed successfully when the session event is caught that means the app hasn't successfully transitionied into its first route and the action should be invoked on the transition; in any other case the action can be invoked on _this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants