Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular: Watch Service for data changes?

I have a service defined as something like this:

appServices.service('SharedData', function() {
    var data = {};

    function setContacts(contacts) {
        data.contacts = contacts;
    };

    function getContacts() {
        return data.contacts;
    };

    return {
        setContacts: setContacts,
        getContacts: getContacts
    };
});

In another controller, I access the data as follows:

$scope.contacts = SharedData.getContacts();

This is all well and good - but I'd like $scope.contacts to be alerted and update it's data whenever the data in SharedData changes.

How do I accomplish this?

like image 355
opticon Avatar asked May 02 '15 00:05

opticon


2 Answers

Be wary of abusing it, but this is just the sort of thing that $rootScope is for:

appServices.service('SharedData', function($rootScope) {
  var data = {};
  function setContacts(contacts) {
    data.contacts = contacts;
    $rootScope.$broadcast('contacts-changed', contacts);
  };
  ...

Now, in any scope you'd like, you can register for this event:

function($scope) {
  $scope.$on('contacts-changed', function(eventObj) {...});
}
like image 23
Michael Hays Avatar answered Sep 28 '22 10:09

Michael Hays


Try an explicit watch:

$scope.$watch(function() { return SharedData.getContacts(); }, function(newContacts) { // Do something with newContacts. });

If elements of the collection can change without the entire collection object changing identity (I assume an Array or Object), you'll need to use $scope.$watchCollection, though that is substantially slower than plain $watch, so avoid if you can make the entire collection change at once.

Note that it might be nicer design to expose a function to the scope that simply returns the current contacts:

$scope.getContacts = function() { return SharedData.getContacts(); };

If you need notification within SharedData, you can inject $rootScope into it and put the $watch onto that.

like image 66
Martin Probst Avatar answered Sep 28 '22 11:09

Martin Probst