javascriptangularjsangularjs-scopeangular-ui-routerangular-broadcast

$broadcast working asynchronously, need to be synchronous


I have a controller which has a number of $rootScope.$broadcast which update the contents of a directive.

The first $rootScope.$broadcast is clearing all the contents/data whilst the other populates it.

app.controller('MyController', function($scope, header) {

    $rootScope.$broadcast('clear');
    $rootScope.$broadcast('title', header.title);
    $rootScope.$broadcast('total', header.total);

});

Note: header is resolved from my $stateProvider e.g:

.state('index', {
        url: '/index',
        templateUrl: 'home.html',
        controller: 'MyController',
        resolve: {
            header:  function() {
                return {
                    title : 'Welcome to Home',
                    total : 6
                };
            }
        }
    })

directive:

app.directive('myDirective', function() {
    return {
        restrict: 'A',
        replace: true,
        scope: {},
        link: function(scope, element, attrs) {
            scope.$on("clear", function(event, val) {
                scope.Title = '';
                scope.Total = 0;
            });               
            scope.$on("title", function(event, title) {
                scope.Title = title;
            });
            scope.$on("total", function(event, total) {
                scope.Total = total;
            });
        },
        template:
            '<section>' +
                '<p>{{Title}} - {{Total}}</p>' +                        
            '</section>'
    }
});

The problem I am having is that on page load, the $broadcast of title and total appear to be being called before clear has completed.


UPDATE:

Plunker: http://plnkr.co/edit/o7wEFyIGh0284ZAc9VnS?p=preview

Whenever on the home.html, the directive will hide - correct. Whenever on the cart.html, the directive will show - correct.

To see issue, click on Cart... Click the button to increment counter.. Then go back to home, then back to Cart... the counter will not reset to 0


Solution

  • As mentioned in my comment above, the problem was that scope.Total within 'clear' was/is not accessible in other .on casts. So, a global variable has been declared and updated within each broadcast:

    app.directive('myDirective', function() {
      return {
        restrict: 'A',
        replace: true,
        scope: {},
        link: function(scope, element, attrs) {
    
          var localTotal = null;
    
          scope.$on("clear", function(event) {
            scope.Title = '';
            scope.Total = 0;
            localTotal = scope.Total;
          });
          scope.$on("showDirective", function(event, show) {
            scope.showDirective = show;
          });
          scope.$on("total", function(event, total) {
            if (localTotal !== 0) {
              console.log("in IF");
              scope.Total = total;
            }
            else {
              scope.Total = localTotal;
            }
          });
          scope.$on("title", function(event, title) {
            scope.Title = title;
          });
        },
        template: '<section>' +
          '<p ng-if="showDirective">{{Title}} - {{Total}}</p>' +
          '</section>'
      }
    });
    

    See Plunker: http://plnkr.co/edit/2Xx99RzvQtaD9ntiod0d?p=preview