5

I'm just starting with AngularJS and as I was always used to work at server side I'm having some difficulties on getting things done, specially debugging code and finding out what the error might be.

I've seen lots of people using the event $stateChangeStart to validate user authentication. I'm trying to do this, but when I try to inject my service into run method, I always get undefined service. Here is my call:

angular
    .module('module_name')
    .config(config)
    .run(function($rootScope, $state, authService) {
        $rootScope.$state = $state;

        $rootScope.$on("$stateChangeStart", function(event, toState, toParams, fromState, fromParams) {
            if (toState.authenticate && !authService.isLoggedIn()) {
                $state.go("login");
                event.preventDefault();
            }
        });

    });

Code:

EDIT 1:

Includes:

<!-- Angular App Script -->
<script src="js/app.js"></script>
<script src="js/services/authService.js"></script>
<script src="js/config.js"></script>
<script src="js/directives.js"></script>
<script src="js/controllers/MainCtrl.js"></script>
<script src="js/controllers/LoginCtrl.js"></script>

js/app.js:

(function () {
    angular.module('module_name', [
        'ui.router',
        'ui.bootstrap',
        'LocalStorageModule',
    ])
})();

authService.js:

angular
    .module('module_name')
    .factory('authService', ['$http', '$q', '$rootScope','localStorageService', function ($http, $q, $rootScope, localStorageService) {

    var serviceBase = 'http://url';
    var authServiceFactory = {};

    var _authentication = {
        isAuth: false,
        userName : ""
    };

    var _saveRegistration = function (registration) {

        _logOut();

        return $http.post(serviceBase + 'account/register', registration).then(function (response) {
            return response;
        });

    };

    var _login = function (loginData) {

        var deferred = $q.defer();

        $http.get(serviceBase + 'account/token', { headers: { 'username': loginData.userName, 'password': loginData.password } }).success(function (response, status, headers, config) {

        localStorageService.set('authorizationData', { token: headers('token'), userName: loginData.userName });

        _authentication.isAuth = true;
        _authentication.userName = loginData.userName;

        deferred.resolve(response);

    }).error(function (err, status) {
        _logOut();
        deferred.reject(err);
    });

    return deferred.promise;

    };

var _logOut = function () {

    localStorageService.remove('authorizationData');

    _authentication.isAuth = false;
    _authentication.userName = "";

};

var _isLoggedIn = function()
{
    return _authentication.isAuth;
}

authServiceFactory.isLoggedIn = _isLoggedIn;

return authServiceFactory;
}]);

config.js:

function config($stateProvider, $urlRouterProvider, $locationProvider) {
    $urlRouterProvider.otherwise("/");
    $stateProvider
        .state('login', {
            url: "/",
            templateUrl: "login.html",
            controller: function($scope) {
                $('body').addClass('gray-bg');
            },
            data: { pageTitle: 'Example view' },
            authenticate: false
        })
        .state('main', {
            url: "/main",
            templateUrl: "views/main.html",
            data: { pageTitle: 'Example view' },
            authenticate: true
        })
        .state('minor', {
            url: "/minor",
            templateUrl: "views/minor.html",
            data: { pageTitle: 'Example view' },
            authenticate: true
        });
    //$locationProvider.html5Mode(true);
}
angular
    .module('module_name')
    .config(config)
    .run(['$rootScope', '$state', 'authService', function ($rootScope, $state, authService) {
        $rootScope.$state = $state;

        $rootScope.$on("$stateChangeStart", function(event, toState, toParams, fromState, fromParams) {
            if (toState.authenticate && !authService.isLoggedIn()) {
                $state.go("login");
                event.preventDefault();
            }
    });

}]);

I've read a little bit and saw that there is an order to inject services, providers and factories, but i can't get it to work. What am I doing wrong?

6
  • Yes! I always get ReferenceError: authService is not defined. Although it is defined... Commented Sep 20, 2014 at 4:19
  • Did you include the js file for authService in your page? Did you also include the localStorageService package? Commented Sep 20, 2014 at 4:27
  • Please try to define authService before the run function.And then use it. Commented Sep 20, 2014 at 4:39
  • Yes! I've added authService and localStorageService. I'll edit my code to show this parts. Commented Sep 20, 2014 at 4:41
  • I have defined AuthService in a separate js file and included it before the one that defines the run method. Commented Sep 20, 2014 at 4:42

1 Answer 1

6

I don't know exactly the cause of the error, but the code above is working. For those that might face the same issue, I think the error was with the following line:

.run(['$rootScope', '$state', 'authService', function ($rootScope, $state, authService) {

Prior to this, it had no brackets [] and only authService was injected like this:

.run('authService', function (authService) {

So, remember to add all and to add brackets. I don't really know why this brackets, if there is any difference with or without them (someone could help me with this), but this is the way my code worked.

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

2 Comments

The square brackets are one way to do dependency injection where the last element in the array is the function. You can also do implicit injection by relying on function parameter names or by setting an array on the function (fn.$inject=['authService']). More info is available on the docs: docs.angularjs.org/guide/di
Additionally, the only way to avoid using the array notation is just: .run(function (authService) {, but might cause problems with minimization.

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.