1
<div class="col-xs-4 col-sm-4 col-md-4">
    {{jsonData[current].profilepic}}
    <div ng-if=IsValidImageUrl(jsonData[current].profilepic)>
        <img id="pic" ng-src="{{jsonData[current].profilepic}}"  alt=""/>
    </div>
    <div ng-if=!IsValidImageUrl(jsonData[current].profilepic)>
        <div id="pic" class="letter">
            <div class="circle">{{jsonData[current].firstName.charAt(1)+jsonData[current].lastName.charAt(1)}}</div>
        </div>
    </div>
</div>

controller:

app.controller('task1Controller',['$scope', 'taskFactory', '$state', 'imageTestService', function($scope, taskFactory, $state, imageTestService){

    $scope.taskData = {};
    $scope.current = 0;

    taskFactory.get().then(function(response){
        $scope.jsonData = response.data.data.resultCareGivers;
    });

    $scope.IsValidImageUrl = function(url){        
        return imageTestService.IsValidImageUrl(url); //Error here
    };

    $scope.viewDetails = function(){
        $state.go('view-details', {details: $scope.jsonData[$scope.current]});
    };


    $scope.back = function(){
        $scope.current = ($scope.current !== 0 ? $scope.current - 1 : 0);
    };

    $scope.next = function(){
        $scope.current = ($scope.current !== $scope.jsonData.length-1 ? $scope.current + 1 : $scope.jsonData.length-1);
    };

}]);

image test service:

app.service('imageTestService', function($q){

    this.IsValidImageUrl = function(url){
        var deferred = $q.defer();
        if(url != null && url != ""){
            var img = new Image();
            img.onerror = function() { deferred.resolve(false); };
            img.onload =  function() { deferred.resolve(true); };
            img.src = url;
            return deferred.promise;
        }
    };

});

Error stack in console:

Error link

10 $digest() iterations reached. Aborting! Watchers fired in the last 5 iterations: [[{"msg":"IsValidImageUrl(jsonData[current].profilepic)","newVal":{"$$state":{"status":0}},"oldVal":{"$$state":{"status":0}}}],[{"msg":"IsValidImageUrl(jsonData[current].profilepic)","newVal":{"$$state":{"status":0}},"oldVal":{"$$state":{"status":0}}}],[{"msg":"IsValidImageUrl(jsonData[current].profilepic)","newVal":{"$$state":{"status":0}},"oldVal":{"$$state":{"status":0}}}],[{"msg":"IsValidImageUrl(jsonData[current].profilepic)","newVal":{"$$state":{"status":0}},"oldVal":{"$$state":{"status":0}}}],[{"msg":"IsValidImageUrl(jsonData[current].profilepic)","newVal":{"$$state":{"status":0}},"oldVal":{"$$state":{"status":0}}}]]

Update 2:

app.service('imageTestService', function(){

    this.IsValidImageUrl = function(url){
        var result = {};
        if(url != null && url != ""){
            var img = new Image();
            img.onerror = function() { result.val = true };
            img.onload =  function() { result.val = false };
            return result;
        }
    };
});

but still the same error in console.

Update 3:

app.service('imageTestService', function(){

    this.IsValidImageUrl = function(url){
        var result = {
            val :false
        };
        this.img = new Image();
        this.img.onabort = function() { result.val = false };
        this.img.onerror = function() { result.val = false };
        this.img.onload =  function() { result.val = true };
        return result.val;
    };
});

In update 3, doesn't matter what I do, always image.onabort() is called.

It throws error fails to load resource at the function call itself:

$scope.IsValidImageUrl = function(url){    //Failed to load resource error    
   return imageTestService.IsValidImageUrl(url); 
};
4
  • What is your question? Commented Aug 8, 2017 at 9:48
  • 1
    Why are u using $q in your service? Commented Aug 8, 2017 at 9:49
  • 1
    Vivz is right, you should return boolean values in IsValidImageUrl function. Commented Aug 8, 2017 at 9:50
  • @GauravSrivastava how do I return boolean. I think image.onerror or image.onload is async Commented Aug 8, 2017 at 10:04

1 Answer 1

1

Short Answer

To get rid of this error we need case where IsValidImageUrl() method should return explicit result.

For example you can initialize result with default value false:

 this.IsValidImageUrl = function(url){
    var result = {
      val:false
    };
    if(url != null && url != ""){
        var img = new Image();
        img.onerror = function() { result.val = true };
        img.onload =  function() { result.val = false };
        return result.val;
    }
};

Demo with 10 $digest() iterations reached error

fixed Demo


Long Answer

First off lets understand why we get 10 $digest() iterations reached. Aborting!. Generally its a guard of Angular to get rid of infinite loop of digest cycles that will cause to memory leak and at the end page stuck.

In our case once IsValidImageUrl will return different result, Angular will fire new digest cycle and so on - that will lead to above mentioned error.


Its not good practice to call methods from ng-if | ng-show/hide | ng-style .... - its a over kill and will effect on your page performance.

I suggest you to call IsValidImageUrl(jsonData[current].profilepic) from controller and store it somewhere. for ng-if we need boolean value only.

FYI, Image.onload and Image.onError are callbacks therefore 1st you return empty object result and after some delay you update result content with Image.onload or Image.onError callbacks that will fire new digest cycle that will lead to additional call of IsValidImageUrl()`.

ngIf directive is a watcher that listens on result and after 10 loops will throw 10 $digest() iterations reached. Aborting! exception.


Sign up to request clarification or add additional context in comments.

3 Comments

Always image.onabort() is called after updating the code.
Thank you. Updated my code with directive and posted a following question here: stackoverflow.com/questions/45571610/…
@kittu will take a look shortly

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.