23

A service with a 3rd party library callback function:

mbAppModule.service('aService', function ($http) {
    this.data={"somedata":0};
    var m3rdPartLib="init";  // init    
    m3rdPartLib.on('timeupdate', function() {
        this.data.somedata=1;
    });
}

And a controller

mbAppModule.controller({
    MController: function ($scope, $http, mService) {
        $scope.mService= mService;    
    });
});

html page

{{mService.data.somedata}}

PROBLEM :

m3rdPartLib.on() is a 3rd party library callback function which i am using it in a service. I want to show it in the ui as it is getting updated. On callback the value is getting changed, but not getting reflected on ui.

Read some docs and found $rootScope.$apply could be called, but i don't have the reference of $scope / $rootScope in the service.

random_user_name
  • 25,694
  • 7
  • 76
  • 115
shrw
  • 1,719
  • 5
  • 27
  • 50

4 Answers4

30

You can take a dependency on $rootScope and call apply in your service.

mbAppModule.service('aService', ["$http", "$rootScope", function ($http, $rootScope) {
    this.data = {
        "somedata": 0
    };
    var m3rdPartLib = "init"; // init    
    m3rdPartLib.on('timeupdate', function () {
        $rootScope.$apply(function(){
            this.data.somedata = 1;
        });
    });
}]);
Mark Coleman
  • 40,542
  • 9
  • 81
  • 101
  • 8
    [jsfiddle](https://jsfiddle.net/gq6kucdg/5/) I feel like it is better if the service should not need to know about the UI. To me it seems like that should fall onto the controller. This is easily done by creating a callback in your service to update the UI. – curlyhairedgenius Jun 16 '15 at 22:18
3

I needed to update an input field from a service because it had listeners and what not that changed data randomly and dynamically.

This could be used to call scope functions in the controller as well:

//scope will be set to current scope of a controller
//which has an ng-view containing this element    
var scope = angular.element('#input-element').scope();
//wrap changes in an apply call to make sure view and model are consistent
scope.$apply(function() {
    scope.object.data = value;
});

Thanks to this post: How do I access the $scope variable in browser's console using AngularJS?

Community
  • 1
  • 1
mattdlockyer
  • 6,984
  • 4
  • 40
  • 44
0

Use $scope.$watch function. Look at my jsfiddle. I haven't your library, so I only simulate it - the value change from 0 to 1 after 5 seconds.

mchrobok
  • 1,947
  • 2
  • 20
  • 22
  • NAH ! this won't help. $timeout is part of angular so it will automatically call the apply and digest to update the scope. – shrw Sep 21 '13 at 11:34
  • 1
    Ok, so please check this http://jsfiddle.net/mchrobok/JE78Q/5/. Does it work? I used events instead of watch. – mchrobok Sep 21 '13 at 11:35
  • 1
    @mchrobok Using a $watch isn't useful in this scenario. In your first fiddle, using `service.data.somedata` in the template reflect the change as well, without requiring a $watch. In your second, calling `$rootScope.$apply()` in the timeout function will trigger the change as well if you use `service.data.somedata` in the template without, one more time, having to use the event mechanism. As long as the reference is valid and a digest cycle is triggered, the value will be updated. – Simon Belanger Sep 21 '13 at 11:41
0

If you´re using scope in your service then it is a good indicator that you´re breaking SRP cause your service should only retrieve data to your controller. My suggestion is that you could do something like this.

mbAppModule.service('aService', ["$http", "$rootScope", function ($http, $rootScope) {
  this.data = {
    "somedata": 0
  };
  var m3rdPartLib = "init"; // init    
  this.GetPartLib = function () { 
    return m3rdPartLib;
  }
}]);

mbAppModule.controller({
  MController: function ($scope, $http, mService) {
  this.GetPartLib = function (){ 
    mService.on('timeupdate', function() {
     this.data.somedata=1;
    });
  }
});
rastasheep
  • 10,416
  • 3
  • 27
  • 37
  • This answer would benefit from some explanation. It may be obvious to some people what this is doing, but to others, especially beginners its not obvious at all. – Paul Rooney Jan 23 '18 at 02:28