33

How can I emit events from a factory or service. I am unable to inject $scope into the factory, thus unable to emit events.

I get the following error - Unknown provider: $scopeProvider <- $scope

Thanks, Murtaza

murtaza52
  • 46,887
  • 28
  • 84
  • 120
  • Why not watch a service variable in the controller(s) instead of emitting events? – Anders Bornholm Dec 16 '13 at 12:09
  • 1
    @AndersBornholm the watch functy in angular is triggered with every digest cycle. Digest cycles can happen quite often depending on the app. Pubsub offers better communication channel. It does not need to eval with every digest cycle. – kitimenpolku Mar 07 '16 at 09:59

3 Answers3

60

Inject $rootScope instead of $scope and then emit it on the $rootScope.

myApp.factory('myFactory', ['$rootScope', function ($rootScope) {
    $rootScope.$emit("myEvent", myEventParams);
}]);

Factories don't have access to the current controller/directive scope because there isn't one. They do have access to the root of the application though and that's why $rootScope is available.

Mathew Berg
  • 28,625
  • 11
  • 69
  • 90
55

You cannot inject a controller's scope into a service. What you can do is:

  • pass the scope instance as a parameter to one of your service functions:

e.g.

app.factory('MyService', function() {

   return {
      myFunction: function(scope) {
         scope.$emit(...);
         ...
      }
    };
});
  • inject the $rootScope into your service:

e.g.

app.factory('MyService', ['$rootScope', function($rootScope) {

   return {
      myFunction: function() {
         $rootScope.$emit(...);
         ...
      }
    };
}]);
asgoth
  • 35,552
  • 12
  • 89
  • 98
  • 15
    Would'nt I do a broadcast from rootscope? – murtaza52 Dec 27 '12 at 17:19
  • I think this is the only way to emit event upwards so that same level controllers don't catch emitted event - if that's what you want (it was in my case) – matko.kvesic Jul 04 '13 at 19:09
  • @murtaza52 You really want to avoid broadcasting. See [What's the correct way to communicate between controllers in AngularJS?](http://stackoverflow.com/a/19498009/1195050) – itsafire Feb 21 '14 at 11:32
  • 1
    Not sure is the right way, this may create a leak when controller is destroyed, what happen to this $scope object? – Thomas Decaux Oct 15 '14 at 09:15
  • @Thomas Decaux I wouldn't use events in the first place (injecting services is the better way), but if you don't keep references to `scope`, it shouldn't create memory leaks – asgoth Oct 17 '14 at 17:39
-1

In your factory inject $rootScope as-

myApp.factory('myFactory',function($rootScope){
return({
// use $rootScope as below to pass myEventParams to all below in hierarchy
$rootScope.$broadcast("myEvent",myEventParams);

})
}]);
  • 2
    I really do not understand voting an answer as not useful without giving proper justification . Highly Unprofessional . – Anand Mohan Singh Jun 14 '17 at 16:23
  • 5
    Well your answer is basically a duplicate of the 5 year old answers above it and doesn't add anything whilst also being less clear than the two existing accepted answers. What information did you think you were adding? – toxaq Jun 27 '17 at 08:57