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.
4 Answers 4
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;
});
});
}]);
1 Comment
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?
Comments
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.
3 Comments
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.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;
});
}
});