0

I am using the $broadcast pattern outlined here to controllers to listen to their service's state.

for example, here I listen to the service's busy/unbusy state to set the mouse cursor.

//Our service
function startRunning(){
     $rootScope.$broadcast("busy"); 
}
function stopRunning(){
     $rootScope.$broadcast("unbusy"); 
}

//Our controller
$scope.$on("busy", function(){
    $scope.state = "busy"; 
}); 

$scope.$on("unbusy", function(){
    $scope.state = "ready"
}); 

HTML

<div ng-controller = "myctrl" ng-state = "state"/> 

CSS:

.busy{
    cursor: wait; 
}

.ready {
    cursor:auto; 
}

The problem with this is that the cursor doesn't change immediately. It usually requires me to move the mouse, I imagine to trigger the $digest cycle, before the cursor changes.

I can fix that with

$scope.$apply($scope.state = "ready"); 

But this will throw up:

Error: [$rootScope:inprog] $digest already in progress

errors.

What is the best way to deal with this?

Edit: here's a working JSFiddle: http://jsfiddle.net/HB7LU/23512/

The issue appears to be something to do with using non-angular timeout/asynchronous methods. (ie. issue doesn't appear if using a $timeout, but does appear if using a setTimeout;

Community
  • 1
  • 1
dwjohnston
  • 11,163
  • 32
  • 99
  • 194
  • Suggest you create a simple demo in [plunker](http://plnkr.co/edit/?p=catalogue) or other sandbox site that replicates your problem. browser may not react immediately to cursor style change without some movement. Also not clear at all what is triggering your state changes – charlietfl Feb 08 '16 at 22:53
  • Use `$timeout(function(){$scope.$apply('state = "ready"')});`. `$timeout` allows for a "safe apply". – georgeawg Feb 08 '16 at 22:57
  • @charlietfl - Yip, that's what i'm upto now and.... I can't reproduce it. :-/ – dwjohnston Feb 08 '16 at 22:59
  • $charliefl - I've added a fiddle. It looks like it's something to do with `$timeout` vs `setTimeout`. It looks like the solution will be to wrap my broadcasts in a `$timeout`. – dwjohnston Feb 08 '16 at 23:13
  • oh...that wasn't shown in question. `setTimout` isn't in angular context when changing scope – charlietfl Feb 08 '16 at 23:44
  • @charlietfl yeah - the difficulty is that in the actual problem, it's an external JS library where I'm calling the broadcasts from, and so it's hard to tell where/how the context changes. I think the solution is to wrap the broadcasts in a `$timeout` – dwjohnston Feb 09 '16 at 00:06
  • Had you mentioned external library from beginning answer would have been easy and quick nd gotten to same point you are now – charlietfl Feb 09 '16 at 00:08

0 Answers0