0

This is my repeater:

<div ng-click="selected(entity)" ng-if="entity.is_organization == true">
    <div class="row">
        <div class="cell info">
            <span class="text" ng-bind-html="entity.label"></span>
        </div>
        <div class="cell img" ng-show="isImageAvailable">
            <img class="image" ng-src="checkImageAvailable(entity.thumbnail[0])">
        </div>
    </div>
</div>

checkImageAvailable in the controller:

$scope.isImageAvailable = false;
$scope.checkImageAvailable = function(image_url){
  var img = new Image();
  img.onload = function (){
    $scope.isImageAvailable = true;
  };
  img.onerror = function (){
    $scope.isImageAvailable = false;
  };
  img.src = image_url;
  if($scope.isImageAvailable){
     return image_url;
  }
};

I get the entity.thumbnail[0] from the JSON, but even it has a URL it doesnt exist. So I do check it using checkImageAvailable. If image is not available, set isImageAvailable set to false, so image parent container ng-show is taken care to hide the image placeholder from browser. Same time on the console log it shows: http://localhost/checkImageAvailable(entity.thumbnail[0]) is 404

What may be the mistake I'm doing in front of AngularJS.

1
  • onload is asynchronous so your function will never return the url. Commented Sep 24, 2015 at 2:46

1 Answer 1

2

One thing that's wrong is that by the time you set:

$scope.isImageAvailable = true; //or false

you're outside the angular lifecycle - so you have to call $scope.$apply();

Any time you make changes to the angular scope outside of an angular event, you have to call $apply().

Checking isImageAvailable will probably be false as onerror/onload will be called back asynchronously so you could just return image_url right away.

Edit

So it turns out that you would have to call the method like:

ng-src="{{checkImageAvailable(entity.thumbnail[0])}}"

But there's a problem because angular keeps calling the method in a loop. Even if you do:

ng-src="{{::checkImageAvailable(entity.thumbnail[0])}}"

it still gets called 3 times. I don't know why 3.

So at this point I would try with a different approach: custom directive. When it initializes you set the image as hidden, attach the onload/onerror handlers to the element and then depending on which gets called, you show the image or not.

Let me know if it doesn't make sense. Demo: http://jsbin.com/yenipodimi/1/edit?html,js,output

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

2 Comments

$scope.$apply(function () { $scope.isImageAvailable = true; // or false; }); Is that what you mean by?
You can do it like that, or just call $scope.$apply(). I created a jsbin example .. but for some reason it calls the new image over and over

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.