Maksim Morozov
Maksim Morozov

Reputation: 191

What wrong with my js code?

I tried to send data from JavaScript to html with Angular... I have this code

phonecatControllers.controller('start', ['$scope', function($scope){
    $scope.lloadd=true; 
    console.log('data - '+$scope.lloadd); 

    function second_passed() {
        $scope.lloadd=false; 
        console.log('data - '+$scope.lloadd); 
        alert('sdasd');
    }
    setTimeout(second_passed, 3000); 
}]);

And this HTML code

<div  ng-show="lloadd">
12312312
</div>

When I start app DIV is visible...but after 3 sec i see only alert... This is my log

01-08 16:34:25.608: I/chromium(22042): [INFO:CONSOLE(179)] "data - true", source: file:///android_asset/www/js/controllers.js (179)

01-08 16:34:28.613: I/chromium(22042): [INFO:CONSOLE(182)] "data - false", source: file:///android_asset/www/js/controllers.js (182)

Upvotes: 0

Views: 121

Answers (2)

ewooycom
ewooycom

Reputation: 2721

You must use angularjs $timeout instead of setTimeout. With setTimeout angular doesn't get notified that something changed, but with $timeout it does.

But you can also use $scope.$apply() in your second_passed(), but I do not recommend that.

Upvotes: 3

Ed_
Ed_

Reputation: 19098

The problem is you're using setTimeout to cause a change to angular data on the $scope that angular doesn't know about.

You need to read about angular's $digest cycle, but in short, you need to tell angular that some event has happened.

For timeouts, angular provides a service that does this for you, appropriately named $timeout, so it's very simple:

phonecatControllers.controller('start', function($scope, $timeout){
 $scope.lloadd=true; 
 console.log('data - '+$scope.lloadd); 
 function second_passed() {
    $scope.lloadd=false; 
    console.log('data - '+$scope.lloadd); 
    alert('sdasd');
 }
 $timeout(second_passed, 3000); 
});

Of course be sure to add $timeout to the arguments to your controller function to ensure it gets injected.

Note that you can achieve the same result using $scope.$apply() to trigger a digest inside your second_passed function:

function second_passed() {
  $scope.$apply( function () {
    $scope.lloadd=false; 
  });
  console.log('data - '+$scope.lloadd); 
  alert('sdasd');
}

But this is not advisable for a couple of reasons:

  1. It's more code!
  2. Manually triggering digests using $scope.$apply() can cause problems if there is another digest in progress already, so it's generally best to avoid it.
  3. $timeout adds more than just a $scope.$apply wrapper - it also returns a promise, and has a handy flush() decorator when you're testing.

Whether you are in the habit of using promises and writing tests or not, you should use $timeout, because someday you will want to use those features.

Upvotes: 1

Related Questions