Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Show Image Element only if image exists in Angular

I have two sibling elements. One is image and other is a div. I want to show image element if image exists and show div element if image doesn't exist. My elements looks like

 <img ng-show="product.img" ng-src="{{product.img}}" />
 <div class="left margin-right-1 line-height-15" ng-hide="product.img">{{product.img}}</div>

And product.img results in something like /assets/images/prod.jpg. As this is a string so ng-show will always be true and image tag will be shown. So if image doesn't exist it will show as broken image. So basically what I want is if image doesn't exist, image tag hides and div is shown and vice versa.

I have tried a javascript function like

 $scope.imageExists = function(src) {
  var image = new Image();
  image.src = src;
  if (image.width == 0) {
      return false;
  } else {
      return true;
  }
}

And changed my image tag like

 <img ng-show="product.img" ng-src="{{imageExists(product.img)}}" />

But this is very expensive. I have 100 products per page and when it loops through all images, the page becomes very very slow.

So can any body guide me what is the best way in angular to show and hide image element if image exists or not.

like image 744
Awais Qarni Avatar asked Apr 29 '16 14:04

Awais Qarni


2 Answers

Use onError event in the image to disable the variable that is used in ng-show

<img ng-show="product.img" ng-src="{{product.img}}" onError="angular.element(this).scope().product.img = false"/>
like image 87
Charlie Avatar answered Sep 22 '22 01:09

Charlie


You can accomplish this using a custom directive. See Plunker: http://plnkr.co/edit/yBb0rNiXIaO4EGTqCAmm?p=preview

You'll need to attach an is404 to each of your image:

for(var i = 0; i < products.length; ++i) {
    products[i].image.is404 = false;
}

Then display them. You'll need to pass $index as an index attribute so you can use it in your directive.

<img ng-if="!image.is404" on-src-error index="{{$index}}" src="{{image.image}}" />
<div ng-if="image.is404">Uh oh!  Image 404'd.</div>

Custom directive:

app.directive("onSrcError", function() {
  return {
    link: function(scope, element, attrs) {
     element.bind('error', function() {
       //set 404 to true and apply the scope
       scope.images[attrs.index].is404 = true;
       scope.$apply();
     });
    }
  };
});
like image 40
Kyle Avatar answered Sep 20 '22 01:09

Kyle