0

I'm having a issue in my Angular app with regards to the resolve section of the ui-router. I'm trying to present a login modal the first time a user hits the website.

In my app.config.js, how do I inject my 'loginService':

angular
    .module('rage')
    .config(config);

function config($stateProvider, $urlRouterProvider) {
    $urlRouterProvider.otherwise("/dashboard");
    $stateProvider
        .state('main', {
            url: "/dashboard",
            templateUrl: "app/views/dashboard.html",
            controller: 'MainCtrl',
            data: { pageTitle: 'RAGE', requireLogin: true },
            resolve: {

                 // *** WHERE DO I INJECT 'loginService' ? ***

                authUser: function () {
                    return loginService.loginModal().then(function (user) {
                        $rootScope.userID = user.userId;
                        userService.openUserSession(razorEnvJson).then(function (data) {
                            // assign some scope vars here..
                        });
                    })
                }
            }
        })
        .state('login', {
            url: "/login",
            templateUrl: "app/views/login-view.html",
            controller: 'LoginCtrl'
        })
}

loginService code:

(function () {
    'use strict';

    angular.module('rage').service('loginService',
        ['$rootScope', '$modal', 'datacontext', 'userService', login]);

    function login($rootScope, $modal, datacontext, userService) {
        var modalInstance = null
        
        this.loginModal = function(){
            modalInstance = $modal.open({
                animation: true,
                templateUrl: 'app/components/login/login.html',
                controller: 'LoginCtrl as login',      
            });            
            return modalInstance.result.then(function (user) {                
                return user;
            });
            
        };

    }
})();

LoginCtrl controller code:

(function () {
    'use strict';

    angular.module('rage').controller('LoginCtrl',
        ['$rootScope', '$scope', '$modalInstance', '$q', 'datacontext', 'userService', authenticate]);

    function authenticate($rootScope, $scope, $modalInstance, $q, datacontext, userService) {

        var login = this;

        // OK,CANCEL CLICK EVENTS FROM MODAL !!!
        $scope.ok = function () {
            //  var user = userService.authenticateWebUser();  // **** TBD ****              
            var user = {userId: login.userId, pswd: login.pswd};
            $modalInstance.close(user);
        };
        $scope.cancel = function () {
            $modalInstance.dismiss('cancel');
        };

    }
})();

I've also attempted $rootScope.$on('$stateChangeStart' event inside app.js to transition the state from main to login, but that hangs up on me.

**** MY UPDATED APP.CONFIG.JS CODE, SEPT 18 ****

Here is the proper usage of resolve: using ui-router states.

function config($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise("/dashboard");
$stateProvider
.state('main', {
    url: "/dashboard",
    templateUrl: "app/views/dashboard.html",
    controller: 'MainCtrl',
    data: { pageTitle: 'RAGE', requireLogin: true },
    resolve: {
	authUser: ['$rootScope', 'loginService', 'userService', function ($rootScope, loginService, userService) {
	    return loginService.loginModal().then(function (user) {
		$rootScope.userID = user.userId;
		initSession(user, $rootScope, loginService, userService);	
	    })
	}]
    }
})
.state('login', {
    url: "/login",
    templateUrl: "app/views/login-view.html",
    controller: 'LoginCtrl'
})
}
function initSession(user, $rootScope, loginService, userService) {

    userService.getInitParams().then(function (envJson) {
        // some code omitted here...
	userService.openUserSession(envJson).then(function (data) {
	    var sessionID = data.data[0];
	    $rootScope.rageSessionVars.sessionID = sessionID;
	    $rootScope.rageSessionVars.userID = $rootScope.userID; // *** HOW TO SUSPEND ALL CODE UNTIL userID IS ASSIGNED ??? ***
	    console.log("sessionID = " + sessionID);

	    $rootScope.rageSessionVars.currDashboardName = "Default";
	});
           
    });

}

* MainCtrl controller code *

(function () {
    'use strict';
    angular.module('rage')
        .controller('MainCtrl',
            ['$rootScope', '$scope', '$interval', '$window', '$state', '$location', 'widgetDefinitions',
            'defaultWidgets', 'gadgetInitService', main]);

    function main($rootScope, $scope, $interval, $window, $state, $location, widgetDefinitions, defaultWidgets, gadgetInitService, authUser) {
        var main = this;
           
        **** authUser IS NEVER DEFINED !!!

        if ($scope.userID == undefined) {   /// *** NOTHING WORKS HERE !!! ***
            //$state.go('login');
            //$location.url('index.html#/?login');
            //return ;
        }

        if ($scope.userID == undefined) {
            main.userName = "risk user";
        }
        else {
            $scope.main.userName = $scope.userID;   
        }
    }
})();

1 Answer 1

2

Edit:

I see your getting confused on the use of 'Resolve'. It should be used when you want some data passed into the controller when it's being run. Not to run a function before initiating a controller.

This isn't what you really want in this situation.

It kinda depends on your authentication method, cookies/tokens etc. Here is a similar method that I would follow.

  • Have a Login service which handles the following -- Login/Logout of the user -- Checks if the user is authenticated

  • In your Controller call your service to check if the user is logged in. -- If the user is not logged in, then prompt login screen -- If the user is logged in, then let the controller continue execution

  • How I handle it, is whenever the user makes an UnAuthorised request where the server returns a 401 response I call my LoginService to prompt the login screen again.

  • I use an authInterceptor in Angular to catch any 401 response from the server. Here is a nice guide on it: http://onehungrymind.com/winning-http-interceptors-angularjs/

This allows you to write your Unauthorized handler in one place.

Hope that makes it a bit clearer.

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

5 Comments

injecting loginService now works, based on your answer ! But I don't understand how to pass in authUser to MainCtrl. Is that passing by default, and I just have to add a parameter to MainCtrl ?
Just add 'authUser' as a parameter to your 'MainCtrl'. Be sure it's the same name as used in the 'resolve'. The parameter will be populated by ui-router for you in the 'resolve'. Then in the 'MainCtrl' you can check if 'authUser' has a value. If it does not then redirect to the login screen.
I've added 'MainCtrl' module above, but authUser is not passed in at all. Thank you.
Updated my answer to reflect what you're looking for. I don't believe a resolve it what you need.
the resolve was an excellent tutorial for me, and it did actually work. I was still able to assign the userID onto the $scope object, which was then available on the MainCtrl controller code. However, I'm seeing now that there are better solutions (i.e. using app.js to check for a user authentication without the resolve). Thank you again.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.