0

I have diagnosed the problem of using ng-show when using an asynchronous call, specifically using google javascript client libraries - gapi.

I have this in my partials/html pages in my angular app. I will use ng-show as follows. This is where I call the ng-show:

<div ng-show="isRegistered()"></div>

When running my battery of tests, ng-show DOES NOT go into an endless loop when I simply do a return call of some boolean value. For example:

$scope.isRegistered = function () {
$scope.test = false;
return $scope.test;};

Furthermore, there is NO endless loop when I go into another function and toggle $scope.test to true or false indefinitely with say, a simple check box.

The problem of this endless loop begins as soon as my return is dependent on some type of asynchronous call like this:

    $scope.isRegistered = function () {
      $scope.test=false;

      var joe = function () {
      var deferred = $q.defer();
      gapi
      .client
      .conference
      .isRegistered()
      .execute(function (res) {
        $scope.$apply(function () {
          if (res.error) {
            $log.error('There was an Error');
            deferred.reject(res.error);
          }
          else {
            $log.info("Success");
            deferred.resolve(res.data);
          }
        });
      });
      return deferred.promise;
      };

    joe()
      .then(function (data) {
        $log.info("Got some data", data);
        $log.info("testing");
        $scope.test = data;
        $log.info($scope.test);
      });

    $log.info($scope.test);
    return $scope.test;

};

It keeps on outputting the following in an endless loop:

  1. Success
  2. Got some data true <- Boolean Value of true
  3. testing
  4. true <--Boolean Value of true
  5. false <- Boolean Value of false

I suspect though, printing false at the end, it does not return false; it does not return anything.

When I switch ng-show to ng-init like this:

<div ng-init="isRegistered()"></div>

I get the output without an endless loop:

  1. false
  2. Success
  3. Got some data true
  4. testing
  5. true

So with an ng-init, it appears it returns the $scope.test global to true - hence it terminating. With ng-show, due to the nature of the async gapi calls, and maybe just the nature of ng-show, though I ask for a return value, it never returns anything. I do not know why.

However, I am confused because the joe() function body - the async gapi call -appears to be successfully called asynchronously, but the isRegistered() function body never "knows" that it is done - hence this loop.

How can I got about letting isRegistered()/ng-show know that the async gapi call is done and return either true or false, and NOT constantly stay in this state of an endless loop. It appears to me, from the way I have it coded, it never returns anything. How do I make it so that isRegistered() would return either true or false based upon the return of the async gapi call?

vama89
  • 5
  • 4
  • 1
    What you are doing is senseless when all you need to do is set a scope variable and pass that to `ng-show`. Need to read up on how angular digest cycles work. `ng-show` expects a synchronous expression, not a promise and that promise is different each digest causing more digests .. ergo an endless loop – charlietfl Aug 12 '15 at 00:51
  • Senseless only because I'm stuck trying to initialize this page via an asynchronous call. The only way I could do that was with ng-init, and that method wasn't working either when I refresh the page, so I tried this "hacky" way with ng-show, but now I know that it expects only a synchronous expression from what you just commented. Thanks though for this term "digest cycles." I'll keep it in the back of my mind when debugging this thing. – vama89 Aug 12 '15 at 03:13
  • i think a better answer is on http://stackoverflow.com/questions/20913569/angularjs-ng-show-method-getting-called-way-too-many-times – shereifhawary May 30 '16 at 16:11

0 Answers0