Godshand
Godshand

Reputation: 631

Calling a $scope in a timeout function

I have 2 inputs here, one is setting the value using scope and the other is setting the value after the setTimeout, but my problem here is that... it doesn't show the value immediately and I need to click the second input to show the value. Any solution for this?

angular.module('selectExample', [])
  .controller('ExampleController', ['$scope', function($scope) {
    $scope.firstInput = "click the second input";
    $scope.secondInput;
    
    function init(){
     setTimeout(function(){ 
     $scope.secondInput = "second input";
     }, 1000);
    } 
    init();
  }]);
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<div ng-app="selectExample" ng-controller="ExampleController">
<input type="text" ng-model="firstInput"></input>
<input type="text" ng-model="secondInput"></input>
</div>

Upvotes: 1

Views: 753

Answers (3)

barbsan
barbsan

Reputation: 3458

Use $timeout instead of setTimeout

angular.module('selectExample', [])
  .controller('ExampleController', ['$scope', '$timeout', function($scope, $timeout) {
    $scope.firstInput = "click the second input";
    $scope.secondInput;
    
    function init(){
     $timeout(function(){ 
       $scope.secondInput = "second input";
     }, 1000);
    } 
    init();
}]);
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<div ng-app="selectExample" ng-controller="ExampleController">
  <input type="text" ng-model="firstInput"></input>
  <input type="text" ng-model="secondInput"></input>
</div>

AngularJS modifies the normal JavaScript flow by providing its own event processing loop. This splits the JavaScript into classical and AngularJS execution context. Only operations which are applied in the AngularJS execution context will benefit from AngularJS data-binding, exception handling, property watching, etc.

For more information, see

Upvotes: 4

Jazib
Jazib

Reputation: 1381

First of all you should follow the solution given by @barbsan. using $timeout instead of setTimeout. That being said you'd still want to $scope.$apply().

to do that if you look into angularjs docs for $timeout, the third parameter is for that. so You can just do the following

$timeout(function() {
              $scope.secondInput = "second input";
            }, 1000,true);

Upvotes: 1

mbojko
mbojko

Reputation: 14669

When you update the second input from setTimeout, the change isn't detected, and you must force change detection manually.

I think adding $scope.$digest(); after $scope.secondInput =... should do the trick.

Upvotes: 0

Related Questions