Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS $rootScope.$broadcast not working in app.run

Tags:

angularjs

I have the following code under my AngularJS .run which works perfectly on my local development machine but won't work when uploaded to my client server...after few tests it is obvious that by the time the controller is loaded the event is not triggered yet so most of the functions in the controller depending on this event do not work. Can someone please tell me what I am doing wrong here and how to fix it? Thanks

myApp.run(['AuthDataSvc', '$rootScope', function (AuthDataSvc, $rootScope) {    
    AuthDataSvc.getAuth().then(function(Token){
        $rootScope.$broadcast('Token', Token);
    }, function(status){
        console.log(status);
    });     
}]);
like image 747
MChan Avatar asked Apr 29 '14 11:04

MChan


1 Answers

You are always going to have a race condition. I have a couple alternatives you can do:

1) Use a service. I am not really a fan of this option because it leads to Spaghetti code. And most time you don't want the controller to run until you have logged on. I prefer option 2.

 myApp.run(['AuthDataSvc', '$rootScope', function (AuthDataSvc, $rootScope) {    
    AuthDataSvc.getAuth(); /* no op we will use the service to determine logged in */
}]);


/* inside a controller */
if(AuthDataSvc.isLoggedIn()){
      //do something.
}

2) Use a route.resolve. Resolves are defined on the route and the Controller will only load once it the promise has been set to resolved. I showed you an example for ui-router and ng-route you need to pick your poison. If you dont use ui-router you should consider it.

/* app.config ... route config.. */
var waitForLogon = {
      UserToken: ["AuthDataSvc", function (AuthDataSvc) {
         return AuthDataSvc.logon();
      }]
};

//this is for ng-route
 $routeProvider
   .when('/Book/:bookId', {
      templateUrl: '--',
      controller: 'MyCtrl',
      resolve: waitForLogon
   })


//this is for ui-router 
$stateProvider
     .state('me', {
            templateUrl: '--',
            controller: 'MeCtrl',
            resolve: waitForLogon
 })

/* controller */
 angular.module('yourapp')
    .controller('MyCtrl', ["UserToken", ... , function(UserToken){
                  //User Token will always be here when your Ctrl loads.
   });

/* service code -- */
angular.module('yourapp')
    .service('AuthDataSvc', ["LogonModel", "$q", function(LogonModel, $q) {
        this._q = null;
        var that = this;
        this._doAuth = function(){
           this.getAuth().then(function(Token){ that._q.resolve(Token) }, function(error){that._q.reject(error);}
        };
        this.logon = function () {
            if(!this._q){
              this._q = $q.defer();
               this._doAuth();// <-current auth do here, and resolve this._q when done
            }
            return this._q.promise;
        };
    });
like image 127
Nix Avatar answered Sep 21 '22 14:09

Nix