5

I want to set manual dummy image if particular image is not available on website. Also how to set if that image is deleted on server or not available, in that case also i need to display default image using JS.

gopigoppu
  • 219
  • 2
  • 15

4 Answers4

4

UPDATE: Here is a custom directive version of this answer. I believe it is the best "angular"-approach. It still depends on the service defined in the original answer:

app.directive('imageOrDefault', function (Utils) {
    return {
        restrict: 'A',
        link: function (scope, element, attrs) {
            console.log(attrs);
            Utils.isImage(attrs.imageOrDefault).then(function(result) {
                attrs.$set('src', result);
            });
        }
    }
});

You can use it in your markup as follows:

<img image-or-default="http://r.llb.be/img/search-418.png" height="42" width="42">

Here is a plunkr of this version.


Initial answer:

You can use the ng-src directive to do that and a service to test if the image actually exists. Here is an example of working plunkr you can adapt to fit your exact needs.

There is an isImage()-function which will test an URL and returns a promise. If the URL is a valid image path, the promise is resolved with that URL. If it is not, the promise will be resolved with your default image path.

app.factory('Utils', function($q) {
    return {
        isImage: function(src) {
            var deferred = $q.defer();
            var image = new Image();
            image.onerror = function() {
                deferred.resolve('yourDefaultImagePath');
            };
            image.onload = function() {
                deferred.resolve(image.src);
            };
            image.src = src;

            return deferred.promise;
        }
    };
});

In the markup, I am using ng-src-directive to wait for the resolve of the promise before setting the src-attribute.

<img ng-src="{{result}}" height="42" width="42">

The isImage()-function is called from a controller:

app.controller('MainCtrl', function($scope, Utils) {
    $scope.test = function() {
        Utils.isImage($scope.source).then(function(result) {
            console.log(result);
            $scope.result = result;
        });
    };
});

This solution can be easily adapted to a custom directive. Let me know if you are interested in this approach.

The solution was adapted from: Angular js - isImage( ) - check if it's image by url

Axel
  • 3,331
  • 11
  • 35
  • 58
apairet
  • 3,162
  • 20
  • 23
  • I have completed the answer. rgds – apairet Aug 19 '14 at 06:05
  • So you post nothing but "You can use the ng-src directive to do that." and then come back 40 some-odd minutes later to write a *useful* answer? Due respect, next time I'd wait to post until you can post something useful. – T.J. Crowder Aug 19 '14 at 06:09
  • 1
    You are right. Sorry for that. I was on my smartphone and then came back to answer properly using a real keyboard. – apairet Aug 19 '14 at 06:12
  • So this works by proactively loading the image in a separate `Image` object, then if that succeeds, assigning that same source to the target image, using a default image if not. Neat! But...where does the image path come from? Originally, I mean? The code seems to be using `$scope.source` (which it passes into `isImage`, which uses it as the `src`). Where does that come from? – T.J. Crowder Aug 19 '14 at 06:29
  • If you look at the plunkr, it comes from an 'input'. I will update the answer with a custom directive which I believe is the cleaner solution. – apairet Aug 19 '14 at 07:10
4

This is cross-browser, vanilla JavaScript and comes along without any ugly onerror="" markup:

var sPathToDefaultImg = 'http://lorempixel.com/150/100/abstract/2/Placeholder/';

var replaceImageWithPlaceholderIfNotAvail = function( domImg ) {

  // sanitize domImg
  if ( !domImg || !domImg.nodeName || domImg.nodeName != 'IMG' ) {
    // get all images from DOM
    aImg = document.getElementsByTagName('IMG');
    i    = aImg.length;
    if ( i ) {
      while ( i-- ) {
        replaceImageWithPlaceholderIfNotAvail( aImg[i] );
      }
    }
    return;
  }

  // here is where the magic happens
  oImg         = new Image();       // create new Image
  oImg.onerror = function() {       // assign onerror
    domImg.src = sPathToDefaultImg; // handler function
  };
  oImg.src     = domImg.src;        // set src of new Image

};

// now you can use the function on "auto pilot"
replaceImageWithPlaceholderIfNotAvail()

// or feed with any domImage you like to evaluate
// replaceImageWithPlaceholderIfNotAvail( domCustomImg )
Available: <img src="http://cdn.sstatic.net/stackexchange/img/logos/so/so-logo-med.png" alt="notavail1.jpg"><br>

Not Available: <img src="notavail1.jpg" alt="notavail2.jpg"><br>

Available: <img src="http://cdn.sstatic.net/stackexchange/img/logos/so/so-logo-med.png" alt="notavail1.jpg"><br>

Not Available: <img src="notavail2.jpg" alt="notavail4.jpg">

CODEPEN:

Axel
  • 3,331
  • 11
  • 35
  • 58
3

You can go with the approach below:

var $defaultImage = '...location of default image..';

and then check the image before loading using the ternary operator:

var $src = empty($src) ? $src : defaultImage; // dummy code 

or create a function that will check and return a default image if an image does not exist:

checkImageExist($loc)  {
    check for $loc 
    if $loc is undefined or null then return $defaulImage
}
Axel
  • 3,331
  • 11
  • 35
  • 58
xkeshav
  • 53,360
  • 44
  • 177
  • 245
3

You can try:

function imgError(image) {
    image.onerror = "";
    image.src = "/images/noimage.gif";
    return true;
}
<img src="image.png" onerror="imgError(this);"/>

or:

$("img").error(function () {
  $(this).unbind("error").attr("src", "broken.gif");
});
Axel
  • 3,331
  • 11
  • 35
  • 58
Suchit kumar
  • 11,809
  • 3
  • 22
  • 44