Angular service field is undefined for one controller only

476 views Asked by At

I have defined a simple service:

app.service('AuthenticationService', function() {
  var auth = {
    isLogged: false
  };
  return auth;
});

I use this to set and share the authentication state between controllers. It reads fine in my LoginCtrl:

app.controller('LoginCtrl', ['$scope', '$location', '$window', 'UserService', 'AuthenticationService', 
  function LoginCtrl($scope, $location, $window, UserService, AuthenticationService) {

    $scope.login = function logIn(username, password) {
      if (username !== undefined && password !== undefined) {
        UserService.login(username, password)
        .success(function(data) {
          AuthenticationService.isLogged = true; //sets value correctly
          $window.sessionStorage.token = data.token;
          $location.path("/main");
        })
        .error(function(status, data) {
          console.log(status);
          console.log(data);
        });
      }
    };

    //...

}]);

As it does in MainCtrl:

    app.controller('MainCtrl', ['$scope', '$location', '$window', 'UserService', 'AuthenticationService', 
      function MainCtrl($scope, $location, $window, UserService, AuthenticationService) {

      //...

      $scope.logout = function() {
        console.log("LOGOUT CALLED AT MAIN CONTROLLER. isLogged "
 + AuthenticationService.isLogged); //prints true
        if (AuthenticationService.isLogged) {
          AuthenticationService.isLogged = false;
          delete $window.sessionStorage.token;
          $location.path("/");
        }
      };

    }]);

However it is inaccessible from this controller, even though I'm pretty sure I'm injecting the service correctly:

    app.controller('SearchCtrl', ['$scope', '$location', '$window', 'MovieDataService', 'UserService', 'AuthenticationService', 
      function SearchCtrl($scope, $location, $window, UserService, AuthenticationService, MovieDataService) {

    //...

      $scope.logout = function() {
        console.log("LOGOUT CALLED AT SEARCH CONTROLLER. isLogged: "
 + AuthenticationService.isLogged); //prints undefined
        if (AuthenticationService.isLogged) {
          //UserService.logout();
          AuthenticationService.isLogged = false;
          delete $window.sessionStorage.token;
          $location.path("/");
        }
      };
    //...
    }]);

Why is this happening? I'm not unsetting isLogged anywhere.

2

There are 2 answers

1
tavnab On BEST ANSWER
app.controller('SearchCtrl', ['$scope', '$location', '$window', 'MovieDataService', 'UserService', 'AuthenticationService', 
  function SearchCtrl($scope, $location, $window, UserService, AuthenticationService, MovieDataService) {

should be

app.controller('SearchCtrl', ['$scope', '$location', '$window', 'MovieDataService', 'UserService', 'AuthenticationService', 
  function SearchCtrl($scope, $location, $window, MovieDataService, UserService, AuthenticationService) {

In other words, you need to make sure the order of arguments in your function matches the preceding list of argument names/dependencies.

To quote the AngularJS DI documentation (emphasis mine):

Inline Array Annotation

This is the preferred way to annotate application components. This is how the examples in the documentation are written.

For example:

someModule.controller('MyController', ['$scope', 'greeter', function($scope, greeter) {
  // ...
}]);

Here we pass an array whose elements consist of a list of strings (the names of the dependencies) followed by the function itself.

When using this type of annotation, take care to keep the annotation array in sync with the parameters in the function declaration.

1
lucas On

your injection order is wrong is should be

['$scope', '$location', '$window', 'MovieDataService', 'UserService', 'AuthenticationService', 
      function SearchCtrl($scope, $location, $window, MovieDataService, UserService, AuthenticationService){}]

the name of service and service passed in should be same order