1

Im working on angularjs 1.4. Im trying to have some frontend-cache collection that updates the view when new data is inserted. I have checked other answers from here Angularjs watch service object but I believe Im not overwriting the array, meaning that the reference is the same.

The code is quite simple:

(function(){

  var appCtrl = function($scope, $timeout, SessionSvc){

    $scope.sessions = {};
    $scope.sessions.list = SessionSvc._cache;

    // Simulate putting data asynchronously
    setTimeout(function(){
      console.log('something more triggered');
      SessionSvc._cache.push({domain: "something more"});
    }, 2000);


    // Watch when service has been updated
    $scope.$watch(function(){
      console.log('Watching...');
      return SessionSvc._cache;
    }, function(){
      console.log('Modified');
    }, true);
  };

  var SessionSvc = function(){
    this._cache = [{domain: 'something'}];
  };

  angular.module('AppModule', [])
          .service('SessionSvc', SessionSvc)
          .controller('appCtrl', appCtrl);

})();

I thought that the dirty checking would have to catch the changes without using any watcher. Still I put the watcher to check if anything gets executed once the setTimeout function is triggered. I just dont see that the change is detected.

Here is the jsbin. Im really not understanding sth or doing a really rockie mistake.

Community
  • 1
  • 1
kitimenpolku
  • 2,604
  • 4
  • 36
  • 51
  • [`$watchCollection`](https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$watchCollection) is a better option in your scenario. Regardless of this, you need to run a $scope.$apply in the async callback so Angular updates the view (see http://stackoverflow.com/questions/15112584/using-scope-watch-and-scope-apply-in-angularjs for details) – Rhumborl Jun 06 '16 at 13:38
  • 1
    use the $timeout service. SetTimeout doesnt trigger an apply – yeouuu Jun 06 '16 at 13:39
  • What @yeouuu said - you're injecting the $timeout service in your demo but you're invoking setTimeout. Replace setTimeout with $timeout. – RamblinRose Jun 06 '16 at 13:42

1 Answers1

0

You need to put $scope.$apply(); at the bottom of your timeout to trigger an update. Alternatively you can use the injectable $timeout service instead of setTimeout and $apply will automatically get called.

jsbin

csbarnes
  • 1,873
  • 2
  • 28
  • 35
  • The timeout was just to simulate the asynchronous op. The key is that we need to trigger the update with apply. In this case I was wrapping things with a service over socketio. Since socketio is external to angular $apply must be called. Thanks – kitimenpolku Jun 06 '16 at 14:10