samin payro
samin payro

Reputation: 31

Error: $rootScope:infdig Infinite $digest Loop while using $http.get()

I have a list of buttons on my html page, which when clicked should open a url in a new page. However, some of the urls return http 500 error. So, I want to disable the buttons if the link behind them returns https 500 error. Here are my html and angular js codes. Actually, in html code, there is a loop for going through all resources (shown by r) related to a specific data (using data-ng-repeat), and checking the maintype of the resource, If it was a LINKDOWNLOAD or LINK, a button should appear if the LINK (r.url) does not release error.

To check if the url releases error or not I used isValid(r.url) function. However, I get infinite number of this error:Error: $rootScope:infdig Infinite $digest Loop.

I made many changes to the way I use isValid(link) function. But they were unsuccessful. Any help please? How should I do this task while I have a ng-repeat loop?

Part of html page:

<div class="gn-related-resources"
     data-ng-if="relationFound">
  <h2>{{::title}}</h2>

  <div class=""
       data-ng-repeat="(type, items) in relations track by $index"
       data-ng-if="type && type !== 'thumbnails'">
    <div class="row list-group-item gn-related-item"
         data-ng-repeat="r in items track by $index"
         data-ng-init="mainType = config.getType(r, type);">
       <div class="col-xs-4" data-ng-if="mainType === 'LINKDOWNLOAD' || mainType === 'LINK'" >
        {{isValid(r.url)}}
        <button type="button"
                class="btn btn-default btn-sm btn-block"
                data-ng-show="isValid(r.url)"
                data-ng-click="config.doAction(mainType, r, md)">

        <span class="visible-lg-*">
          {{::(config.getLabel(mainType, type)) | translate}}
        </span>
        </button>
      </div>
    </div>
  </div>
</div>

Part of angularjs directive:

  module
  .directive(
      'gnRelated',
      ['gnRelatedService',
    'gnGlobalSettings',
    'gnRelatedResources',
    function( gnRelatedService, gnGlobalSettings, gnRelatedResources) {
      return {
        restrict: 'A',
        templateUrl: function(elem, attrs) {
          return attrs.template ||
                  '../../catalog/components/metadataactions/partials/related.html';
        },
        scope: {
          md: '=gnRelated',
          template: '@',
          types: '@',
          title: '@',
          list: '@',
          user: '=',
          hasResults: '=?'
        },

        link: function(scope, element, attrs, controller) {

          var promise;
          scope.updateRelations = function() {
            scope.relations = [];
            if (scope.uuid) {
              scope.relationFound = false;
              (promise = gnRelatedService.get(
                 scope.uuid, scope.types)
              ).then(function(data) {
                   scope.relations = data;
                   angular.forEach(data, function(value) {
                     if (value) {
                       scope.relationFound = true;
                       scope.hasResults = true;
                     }
                   });
                 });
            }
          };

Upvotes: 1

Views: 426

Answers (1)

Maxim Shoustin
Maxim Shoustin

Reputation: 77904

I strongly recommend you never do such things: {{isValid(r.url)}}

scope.isValid = function(link)
              {
                $http.get(link).then(
                function(success) {
                   return true;
                }, function(error) {
                   return false;
                });
              };

Every digest cycle you call async call


You have relations list, create Promise all, a.e. $q.all([]) and render results respectively.

Instead isValid(r.url) I would write something like:

{{r.requestSucceeded}}

where requestSucceeded will be created after you run all requests

Upvotes: 1

Related Questions