1

I have been looking for a solution, but I still can't get the $location.path() to work correctly.

The case is simple: after positive authentication, I'm trying to go back to the root address: /#/. The path in the address bar is changing, but the page doesn't. What is curious, when I press "Enter" in the address bar, the page reloads before going to the root address. And what is more curious, I have to hit enter multiple times before it actually redirects me to another page. That's weird, because that's not how the "one-page" approach is supposed to be working.

I'm using Angular Router, and the rest of the page is working correctly. Every screen is loading smoothly after typing its path and pressing "Enter" - no reloading. The only problem is with the authentication step.

When the app is firstly loaded, and the /login page is issued because there are no authentication details saved, the app can be redirected to the root address after positive authentication (yet not always). But when the authentication details are lost while the app is running, and the user is redirected to the /login page, the app just can't go back to the root URL.

I have created a flowchart, which presents how routes are changing. The green area presents the first case, when the user opens up the app and is not logged in yet. The read area presents the second case, when the user loses the authentication details for some reason (e.g. old token, changed password from another source). The user is redirected to /login page, and then after positive authentication, can't go back to the root URL.

Flowchart

I've tried to wrap $location.path('/') in $scope.$apply but received an error, that the digest is actually in progress. Wrapping it in $timeout didn't help as well. I can of course reload the page after changing the path, but it creates an ugly effect of disappearing interface.

Below is the code triggered after pressing the "Login" button.

function doLogin() {
    vm.loginInProgress = true;

    LoginService.login(vm.username, vm.password).then(function () {
        $location.path('/');
    }).catch(function () {
        var confirm = $mdDialog.confirm()
            .title('Authentication error')
            .textContent('Username and/or password is invalid.')
            .ariaLabel('Authentication error')
            .ok('OK')
            .cancel('Forgotten password?');

        $mdDialog.show(confirm).catch(function() {
            //TODO: Forgotten password
        })
    }).finally(function () {
        vm.loginInProgress = false;
    });
}

Routes:

$routeProvider
    .when('/login', {
        templateUrl: 'views/login.html',
        controller: 'LoginController',
        controllerAs: 'vm'
    })
    .when('/', {
        templateUrl: 'views/home.html',
        controller: 'HomeController',
        controllerAs: 'vm',
        resolve: {
            init: init
        }
    });

/* @ngInject */
function init(ConfigService, TemperatureService) {
var ret = {};

return ConfigService.finished()
    .then(function () {
        return TemperatureService.getSetPoint();
    })
    .then(function (data) {
        ret['setpoint'] = data;
        return TemperatureService.getWorkModes();
    })
    .then(function (data) {
        ret['workmodes'] = data;
        return ret;
    });
}

It looks like a weird behavior of location.path method. Or I'm just missing something. Every help will be appreciated.

5
  • 1
    what do you have in resolve Commented Oct 25, 2016 at 13:40
  • Can you show what redirects user to login initially? Commented Oct 25, 2016 at 13:43
  • Replace $location.path('/'); to $location.url('/'); and check. Commented Oct 25, 2016 at 13:44
  • @Sravan two words: 1.THANK 2.YOU! You are my programming duck. It turned out, that one of my promises from init didn't resolve properly and that was blocking the route change. Write the answer, I will accept it as a solution. Commented Oct 25, 2016 at 13:52
  • @itachi, added as an answer. Commented Oct 25, 2016 at 13:57

2 Answers 2

1

In your question you have taken a resolve which executes the code given in that resolve function.

You must have some issue in that init function which you used for resolving.

$routeProvider
    .when('/login', {
        templateUrl: 'views/login.html',
        controller: 'LoginController',
        controllerAs: 'vm'
    })
    .when('/', {
        templateUrl: 'views/home.html',
        controller: 'HomeController',
        controllerAs: 'vm',
        resolve: {
            init: init
        }
    });

Your init can go here,

var init = function ($q, $rootScope, $location) {
    if ($rootScope.login) {
        return true;
    } else {
        $location.path('/login')  // this is a sample
    }
};

You may have some issue in this method. please check once.

Sign up to request clarification or add additional context in comments.

Comments

0

This is likely due to the resolve function init for the route / not resolving correctly.

You can try listening to the $routeChangeError event to see what went wrong.

$rootScope.$on('$routeChangeError', function () {
  ...
});

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.