Jose Mendez
Jose Mendez

Reputation: 43

Angular - alert() executes before view change

Why is it that alert() executes before the change in the view? And how can it be achieved that the view is changed, and then the alert pops up?

var app = angular.module("myApp", []);

app.controller("myCtrl", function($scope) {
  $scope.points = 0;
  $scope.add = function() {
    ++$scope.points;
    alert('This alert appears before the score is changed in the view')
  };
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
  <p ng-click="add()">
    Score: {{ points }}
  </p>
</div>

Upvotes: 0

Views: 164

Answers (2)

Pengyy
Pengyy

Reputation: 38189

This is based on how browser works. The view will rerender only after event has finished but the data has already been changed.

refer the below example I entirely copied from you, except that I add one row console.log. You can confirm by open browser's console to see what happened.

var app = angular.module("myApp", []);

app.controller("myCtrl", function($scope) {
  $scope.points = 0;
  $scope.add = function() {
    ++$scope.points;
    console.log($scope.points);    // open browser to confirm
    alert('This alert appears before the score is changed in the view')
  };
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
  <p ng-click="add()">
    Score: {{ points }}
  </p>
</div>


Normal case without angularjs

function showAlert() {
  document.getElementById("show").innerHTML = '1111';
  alert('Information changed');
}
<span id="show"></span>
<input type="text" onchange="showAlert()">


the tricky example I commented using $timeout

var app = angular.module("myApp", []);

app.controller("myCtrl", function($scope, $timeout) {
  $scope.points = 0;
  $scope.add = function() {
    ++$scope.points;
    console.log($scope.points);    // open browser to confirm
    
    $timeout(function() {
      alert('This alert appears before the score is changed in the view');
    });
  };
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
  <p ng-click="add()">
    Score: {{ points }}
  </p>
</div>

Upvotes: 1

Jerhemy
Jerhemy

Reputation: 590

The issue is that the digest cycle isn't completed before moving to the alert() code. One option would be to wrap your alert in a timeout

 setTimeout(function() {
     alert('This alert appears before the score is changed in the view')
 },1);

var app = angular.module("myApp", []);

app.controller("myCtrl", function($scope) {
  $scope.points = 0;
  $scope.add = function() {
    ++$scope.points;
    setTimeout(function() {
     alert('This alert appears before the score is changed in the view')
    },1);
  };
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
  <p ng-click="add()">
    Score: {{ points }}
  </p>
</div>

Upvotes: 1

Related Questions