0

I have this simple markup : (jsbin)

  <div ng-app data-ng-controller="HelloWorldController">
    <div>
        <label>Message :
            <input ng-model="message">
        </label>
        <h1>{{message}}</h1>
    </div>
</div>

Where :

  function HelloWorldController($scope)
  { var i=0;
    setInterval(function (){i++; 
                            console.log("Hello World "+i);
                            $scope.message="Hello World "+i;},1000);

  }

In the console it does show me the intervals :

enter image description here

But in the View - I don't see it ,and I should see it:

enter image description here

Question :

What am I missing here and why it doesn't update my view ?

John Slegers
  • 45,213
  • 22
  • 199
  • 169
Royi Namir
  • 144,742
  • 138
  • 468
  • 792
  • may be this is useful - http://angular-tips.com/blog/2013/08/watch-how-the-apply-runs-a-digest/ – YOU Jan 03 '14 at 20:23
  • I removed my comment after I reread your post. To better understand what is going on, see this post: http://jimhoskins.com/2012/12/17/angularjs-and-apply.html – Mike Cheel Jan 03 '14 at 20:25
  • here is a working bin. http://jsbin.com/IWedoYiP/9 – calebboyd Jan 03 '14 at 20:35

7 Answers7

1

You need to manually enter angular digest cycle to update views. use $scope.$apply in your controller:

function HelloWorldController($scope) {
  var i = 0;
  setInterval(function () {
    i++;
    console.log("Hello World " + i);
    $scope.$apply(function () {
      $scope.message = "Hello World " + i;
    });
  }, 1000);
}
Daiwei
  • 40,666
  • 3
  • 38
  • 48
1

You should be using Angular's $timeout service (I prefer this over manually causing Angular to run a digest cycle by using $scope.$apply). You don't want your Angular code littered with those statements.

So your code should be (Note that you will have to inject the timeout service):

function HelloWorldController($scope, $timeout){ 
     var i=0;
     $timeout(function () {
          i++; 
          console.log("Hello World "+i);
          $scope.message="Hello World "+i;
        },1000);
}
victormejia
  • 1,174
  • 3
  • 12
  • 30
1

You need to $apply your scope. Edit your code as follows

  function HelloWorldController($scope)
  { var i=0;
    setInterval(function (){i++; 
                            console.log("Hello World "+i);
                            $scope.message="Hello World "+i;
$scope.$apply();
},1000);

  }
Alborz
  • 6,843
  • 3
  • 22
  • 37
  • When you using setInterval your code is executed outside of angular. So you need to aware the angular about the changes by $scope.$apply. http://stackoverflow.com/questions/15112584/using-scope-watch-and-scope-apply – Alborz Jan 03 '14 at 20:38
1

if you add $scope.$apply(); after you have modified your scope it will update the ui.

1

A apply is not occuring. To do this without using an apply (and on an interval) You can use a promise, coincidentally $timeout uses these by default. To make your example work you can do this:

function HelloWorldController($scope,$timeout){
    var i=0;
    (function doStuff() {
        i++;
        console.log("Hello World "+i);
        $scope.message="Hello World "+i;
        $timeout(doStuff, 1000);
    }());   
}

Working JSBin: http://jsbin.com/IWedoYiP/9/

By using timeout. The callback is automatically resolved inside a promise. Which causes a digest. Automatically updating the view.

calebboyd
  • 5,744
  • 2
  • 22
  • 32
1

In a nutshell your call to setInterval is not being picked up by Angular. You need to call $scope.$apply() as mentioned in this article:

http://jimhoskins.com/2012/12/17/angularjs-and-apply.html

which clearly explains the details of what is going.

Also, as mentioned in the article, you should NOT have to use $scope.$apply if you use $timeout instead of setInterval.

Mike Cheel
  • 12,626
  • 10
  • 72
  • 101
1

Using setInterval angularjs don't know what happens so you should do like

app.controller('HelloWorldController',function($scope){
               var i=0;
                setInterval(function (){i++; 
                    console.log("Hello World "+i);
                    $scope.$apply(function(){
                            $scope.message="Hello World "+i;
                        }
                    );   
               },1000);

        });
Whisher
  • 31,320
  • 32
  • 120
  • 201