title: AngularJS : service $broadcast and $watch not triggering on receiving controller
body: <p>AngularJS noob here, on my path to the Angular Enlightenment :)</p>
  
  <p>Here's the situation:</p>
  
  <p>I have implemented a service 'AudioPlayer' inside my module 'app' and registered like so:</p>
  
  <pre><code> app.service('AudioPlayer', function($rootScope) {
  
       // ...
  
       this.next = function () {
           // loads the next track in the playlist
           this.loadTrack(playlist[++playIndex]);     
       };
  
       this.loadTrack = function(track) {
           // ... loads the track and plays it
           // broadcast 'trackLoaded' event when done
           $rootScope.$broadcast('trackLoaded', track); 
       };
   }
  </code></pre>
  
  <p>and here's the 'receiver' controller (mostly for UI / presentation logic)</p>
  
  <pre><code>app.controller('PlayerCtrl', function PlayerCtrl($scope, AudioPlayer) {
  
  
      // AudioPlayer broadcasts the event when the track is loaded
  
      $scope.$on('trackLoaded', function(event, track) {
          // assign the loaded track as the 'current' 
          $scope.current = track;
      });
  
      $scope.next = function() {
          AudioPlayer.next();
      };
  }
  </code></pre>
  
  <p>in my views I show the current track info like so:</p>
  
  <pre><code>&lt;div ng-controller="PlayerCtrl"&gt;
      &lt;button ng-click="next()"&gt;&lt;/button&gt;
      // ...
      &lt;p id="info"&gt;{{current.title}} by {{current.author}}&lt;/p&gt;
  &lt;/div&gt;
  </code></pre>
  
  <p>the next() method is defined in the PlayerCtrl, and it simply invokes the same method on the AudioPlayer service.</p>
  
  <p><strong>The problem</strong></p>
  
  <p>This works fine when there is a manual interaction (ie when I click on the next() button) - the flow is the following:</p>
  
  <ol>
  <li>PlayerCtrl intercepts the click and fires its own next() method</li>
  <li>which in turn fires the AudioPlayer.next() method</li>
  <li>which seeks the next track in the playlist and calls the loadTrack() method</li>
  <li>loadTrack() $broadcasts the 'trackLoaded' event (sending out the track itself with it)</li>
  <li>the PlayerCtrl listens the broadcast event and assigns the track to the current object</li>
  <li>the view updates correctly, showing the current.title and current.author info</li>
  </ol>
  
  <p>However, when the next() method is called from within the AudioService in the 'background' (ie, when the track is over), all the steps from 1 to 5 do happen, but the view doesn't get notified of the change in the PlayerCtrl's 'current' object.</p>
  
  <p>I can see clearly the new track object being assigned in the PlayerCtrl, but it's as if the view doesn't get notified of the change. I'm a noob, and I'm not sure if this is of any help, but what I've tried is adding a $watch expression in the PlayerCtrl</p>
  
  <pre><code>$scope.$watch('current', function(newVal, oldVal) {
      console.log('Current changed');
  })
  </code></pre>
  
  <p>which gets printed out only during the 'manual' interactions...</p>
  
  <p>Again, like I said, if I add a console.log(current) in the $on listener like so:</p>
  
  <pre><code>$scope.$on('trackLoaded', function(event, track) {
      $scope.current = track;
      console.log($scope.current);
  });
  </code></pre>
  
  <p>this gets printed correctly at all times.</p>
  
  <p>What am I doing wrong?</p>
  
  <p>(ps I'm using AudioJS for the HTML5 audio player but I don't think this is the one to blame here...)</p>