6

I am trying to access a global variable via a normal function, is it possible?

I have set some var using $rootScope and I am trying to access this via a callback function. This callback is called from controller. I don't want to pass $rootScope in that callback.

Is there any way to access that $rootScope.var ?

I am open to use service if it is possible.

Please suggest.

Thanks

I am trying to access rootScope as following:

    function fbLandingCtrl($scope, $rootScope) {
    $rootScope.isFBLoggedin = false;
    $scope.login = function() {
       console.log( $rootScope.isFBLoggedin);
       fbHelper.login(getUserInfo);
      };

      function getUserInfo(){
          fbHelper.getUserInfo(updateStatus);
      }
      function updateStatus(userInfo){
          $rootScope.isFBLoggedin = true;
          console.log( $rootScope.isFBLoggedin);
      }
  }

and my service is as:

    myapp.factory('FBService', [ '$rootScope', function ($rootScope) {
    $rootScope.isFBLoggedin = false; // global variable
    $rootScope.userName = null;
    $rootScope.userEmail = null;

    return {

        getStatus: function() {
            return $rootScope.isFBLoggedin;
        },
        setStatus: function(status) {
            console.log("Status:"+status);
            return $rootScope.isFBLoggedin = status;
        }
       };
}]);

it is showing isFBLoggedin as true under updateStatus fn but it is not reflecting on view

I am printing {{isFBLoggedin}} but is ts showing false

Finally Its working.

I followed @dluz's solution.

I also used $rootScope.$apply(function() {}}) to render views

Thirumalai murugan
  • 5,698
  • 8
  • 32
  • 54
A_J
  • 1,635
  • 1
  • 18
  • 31

2 Answers2

5

Please don't use the $rootScope to define any function - it's really bad practice. Remember that $rootScope is a global variable after all.

You can get the $rootScope via service like this:

<!doctype html>
 <html lang="en" ng-app="myApp">
  <head>
<meta charset="UTF-8">
<title>Document</title>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js"></script>

  <script>

     var myApp = angular.module('myApp', []);

      myApp.controller('myAppCtrl', ['$scope', 'myService', function ($scope, myService) {

       console.log(myService.getData());
    
}])

        myApp.factory('myService', [ '$rootScope', function ($rootScope) {
    
       return {
        
        getData: function() {
            return $rootScope;
        }
       };
      }])


    </script>

  </head>
  <body ng-controller="myAppCtrl">

   </body>
   </html>

$rootScope exists, but it can be used for evil

Scopes in Angular form a hierarchy, prototypically inheriting from a root scope at the top of the tree. Usually this can be ignored, since most views have a controller, and therefore a scope, of their own.

Occasionally there are pieces of data that you want to make global to the whole app. For these, you can inject $rootScope and set values on it like any other scope. Since the scopes inherit from the root scope, these values will be available to the expressions attached to directives like ng-show just like values on your local $scope.

Of course, global state sucks and you should use $rootScope sparingly, like you would (hopefully) use with global variables in any language. In particular, don't use it for code, only data. If you're tempted to put a function on $rootScope, it's almost always better to put it in a service that can be injected where it's needed, and more easily tested.

Conversely, don't create a service whose only purpose in life is to store and return bits of data.

UPDATED ANSWER

A_J, I am not sure what's the scenario of your application. I would need to see more code to give you a better answer, but please take a look at the code below. Maybe it can give you some idea how you can design your code to access $rootScope inside a service.

Press the button "Log me In" and take a look at your console. Working example here (http://jsbin.com/olOyaHa/1/)

 <!doctype html>
 <html lang="en" ng-app="myApp">
    <head>
 <meta charset="UTF-8">
 <title>Document</title>
 <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js"></script>

 <script>

     var myApp = angular.module('myApp', []);

     myApp.controller('fbLandingCtrl', ['$scope', '$rootScope', 'loginService', function ($scope, $rootScope, loginService) {

    $rootScope.isFBLoggedin = false;
    
    $scope.login = function() {
       console.log('Current login status', $rootScope.isFBLoggedin);

       console.log(loginService.getUserInfo());

       loginService.login(loginService.getUserInfo());

       loginService.updateStatus();
      };

    
     }]);


     myApp.factory('loginService', [ '$rootScope', function ($rootScope) {
    
    return {
        
        login: function() {
            console.log('now I am logged in!');
            return $rootScope.isFBLoggedin = true;
        },

        getUserInfo: function() {
            return {
                username: 'xmen',
                role: 'admin',
                logged: 'false'
            };
        },
        
        updateStatus: function(userInfo){
            $rootScope.isFBLoggedin = true;
            console.log('Current login status', $rootScope.isFBLoggedin);
        }
        };
     }])


    </script>

 </head>
 <body ng-controller="fbLandingCtrl">
    <button ng-click="login()">Log Me In</button>
 </body>
 </html>
Community
  • 1
  • 1
Denison Luz
  • 3,575
  • 23
  • 25
  • exactly, But can I access that service directly from normal function? – A_J Oct 02 '13 at 13:23
  • 1
    Where is your "normal function" defined ?!? It will be either inside a `directive` or a `controller`, right ?!? So the answer is YES, you just need to add that service as a dependency of your directive or controller. If your normal function is defined somewhere else, that's a code design problem and you will need to review your logic. – Denison Luz Oct 02 '13 at 13:25
  • What do you mean "normal function" ? A function outside any Angular scope ? Sounds like you have a code design problem... – Scalpweb Oct 02 '13 at 13:25
  • Thanks @dluz, Its Service working for me but I am getting issue in view. That isFBLoggedin is not being updated in my view – A_J Oct 02 '13 at 15:22
  • Thanks @dluz and @Scalpweb for your quick response. Now Its working for me, I had to use `$rootScope.$apply(function() {}})` – A_J Oct 02 '13 at 16:20
2

You can access $rootScope.var inside your controller if you added $rootScope as a controller reference:

function MyCtrl($scope, $rootScope, $routeParams /*, ... */)
{
  /* Controller code and callback code here */
}

It will work as long as your callback is defined inside your controller.

EDIT: after our discussion, here is how to define a function inside your rootScope:

yourApp.run($rootScope/*, ResourceProvider ... */) {
    $rootScope.yourFunction= function () {
        /* The code of you functions */
    }
}
Scalpweb
  • 1,971
  • 1
  • 12
  • 14