39wu8g
Last Updated: February 25, 2016
·
623
· dankapusta

Don't circumvent the digest cycle.

It appears that window.setTimeout circumvents the digest cycle in AngularJS. You might have a controller with a function (like the below) that gets some JSON using data from another JSON request (that may or may not be done yet). This won't work if you use window.timeout so use Angular's $timeout instead.

A promise covering the two requests could be used, but in my case the the first chunk of JSON is fetched during the module.run() phase to fetch some user data.

This code assumes AngularJS 1.1.4 (unstable) and an $http service factory named myHttp.

angular.module('yourmodulenamehere').controller("controllername", function($scope, $rootScope, $timeout, myHttp) {
  $scope.items = [];
  $scope.getSomething = function() {
    if ($rootScope.user_id) { // use $rootScope with caution 
      $scope.items = myHttp.get( // pass three things to the GET...
        'someurl', // 1. url
        { "foo": "bar" }, // 2. a params object
        function(obj) { // 3. what to do when the job is done
          if (obj.status === 200) {
            $scope.items = obj.data.items;
          } else {
            console.log("AJAX call failed, status code = " + obj.status);
          }
        }
      );
    } else { // otherwise, try again in a bit
      // Don't use window.setTimeout here, it circumvents the digest cycle
      $timeout($scope.getSomething, 100);
    } // end if
  };
});

If you use window.timeout above any updates made to $scope.items won't be seen by Angular and the view that uses this controller won't be updated.

Say Thanks
Respond