Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

EmberJS: Return to current route after login

Tags:

ember.js

I have an app where anonymous users can see read-only views. When a user clicks a link to log in, I want to save the current route and model and restore it after successful authentication.

This is a little different from most examples that intercept a transition in beforeModel and redirect to log in.

App.ApplicationController = Ember.Controller.extend({
    actions: {
        logIn: function() {
            this.set('previousPath', this.get('currentPath'));
            this.transitionToRoute('login');
        }
    }
});

App.LoginController = Ember.Controller.extend({
    needs: 'application',
    username: '',
    password: '',

    actions: {
        logIn: function () {
            var self = this;

            App.session.logIn(this.get('username'), this.get('password')).then(
                function() {
                    var route = self.get('controllers.application.previousPath')
                    self.transitionToRoute(route);
                });
        }
    }
});

This works fine for static routes, but for dynamic routes the model and route parameters are lost.

How do I capture either the current controller's model or route parameters so I can restore them?

like image 863
Chris Eldredge Avatar asked Jan 14 '14 19:01

Chris Eldredge


2 Answers

I found a way to do this that is similar to the intercept-redirect-retry pattern.

First, remember the most recent transition in the application route as long as it isn't the transition to login:

App.ApplicationRoute = Ember.Route.extend({
    beforeModel: function(transition) {
        this._saveTransition(transition);
    },
    actions: {
        willTransition: function (transition) {
            this._saveTransition(transition);
        }
    },
    _saveTransition: function (transition) {
        if (transition.targetName !== 'login') {
            this.controllerFor('login').set('previousTransition', transition);
        }
    }
});

beforeModel fires when the app is entered or if the page is hard refreshed. willTransition fires on every subsequent transition.

Then LoginController can retry the previous transition after successful authentication:

App.LoginController = Ember.Controller.extend({
    username: '',
    password: '',

    actions: {
        logIn: function () {
            var self = this;

            App.session.logIn(this.get('username'), this.get('password')).then(
                function() {
                    var previousTransition = self.get('previousTransition');

                    if (previousTransition) {
                        previousTransition.retry();
                        return;
                    }

                    self.transitionToRoute('index');
                });
        }
    }
});
like image 116
Chris Eldredge Avatar answered Nov 06 '22 07:11

Chris Eldredge


The guides have a case which seems to be exactly what you are looking for.

App.SomeAuthenticatedRoute = Ember.Route.extend({
  beforeModel: function(transition) {
    if (!this.controllerFor('auth').get('userIsLoggedIn')) {
      var loginController = this.controllerFor('login');
      loginController.set('previousTransition', transition);
      this.transitionTo('login');
    }
  }
});

App.LoginController = Ember.Controller.extend({
  actions: {
    login: function() {
      // Log the user in, then reattempt previous transition if it exists.
      var previousTransition = this.get('previousTransition');
      if (previousTransition) {
        this.set('previousTransition', null);
        previousTransition.retry();
      } else {
        // Default back to homepage
        this.transitionToRoute('index');
      }
    }
  }
});

for more details see STORING AND RETRYING A TRANSITION

like image 26
tikotzky Avatar answered Nov 06 '22 06:11

tikotzky



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!