Reputation: 7008
<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:
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);
};
Upvotes: 1
Views: 897
Reputation: 77904
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
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.
Upvotes: 1