Search code examples
angularjsangular-broadcast

angularjs $broadcast not reflecting values on view


When I add a $broadcast in $rootScope and catch it to other controller, it is not reflecting any value to view. Example:

// on first ctrl.
controller('firstCtrl', ['$scope','$location', '$rootScope', function($scope, $location, $rootScope) {
    $scope.myFunc = function() { 
        $rootScope.$broadcast('someEvent');
        $location.path('/users');
    }
}])


// On Users Page.
.controller('usersCtrl', ['$scope','$rootScope', function($scope, $rootScope) { 
    $scope.dataFilter = {};
    $rootScope.$on('someEvent', function(event, b) {
        $scope.callOnBroadcast();
    });
  
    // call this function on broadcast.  
    $scope.callOnBroadcast = function() {
      $scope.dataFilter = {
        types: [
          {key: 'tags',     val: 'Collections'},
          {key: 'prices',   val: 'Price'},
          {key: 'ratings',  val: 'Rating'},
          {key: 'designers',val: 'Designer'}
        ],
        data: {tags: [], prices: [], ratings: [], designers: []}

      };

      $scope.$apply();


    };
}])
<h4 data-ng-repeat="ftr in dataFilter.types">  
  {{ftr.val}}
</h4>

When I Use MyFunc function on firstCtrl, it will redirect me to user's page, also broadcast function run. On users page, I Use $scope.callOnBroadcast() when broadcast is on, but it is reflecting any change on view page even I use $scope.$apply(). Where am I wrong ?


Solution

  • Your both the controller don't have any hierarchy that's why you need to $broadcast the event in $rootScope rather than scope,

    Your problem is you are broadcasting event before registering listener event. After that you are doing $location.path('/users'), which load user template with usersCtrl.

    I think you should do redirection 1st and then broadcast the event in $rootScope with certain timeout inorder to make available the usersCtrl

    Code

    // on first ctrl.
    controller('firstCtrl', ['$scope','$location', '$rootScope',  '$timeout',function($scope, $location, $rootScope, $timeout) {
        $scope.myFunc = function() { 
            $location.path('/users');
            $timeout(function(){
              //boardcast will available to every listener
              $rootScope.$broadcast('someEvent'); 
            },1000);
        }
    }]);
    

    Make sure the other listener code should be register before broadcasting the event.(Below listener should be registered before broadcasting).

    $scope.$on('someEvent', function(event, b) {
        $scope.callOnBroadcast();
    });
    

    For making it more better solution, you could use resolve of $routeProvider