18

Is it possible to check if by a given url the image exists and it's an image resource ?

for example:

angular.isImage('http://asd.com/asd/asd.jpg')

Or it's just a stuff for the server side ?

NO JQUERY please i'm not using it

2 Answers 2

46

I think the best javascript approach would be to use HTMLImageElement object with deferred object:

function isImage(src) {

    var deferred = $q.defer();

    var image = new Image();
    image.onerror = function() {
        deferred.resolve(false);
    };
    image.onload = function() {
        deferred.resolve(true);
    };
    image.src = src;

    return deferred.promise;
}

Usage:

isImage('http://asd.com/asd/asd.jpg').then(function(test) {
    console.log(test);
});

Using HTMLImageElement gives you some benefits: not only it tests that the file is downloadable but also it is valid image resource that can be displayed by img tag.

I wrapped this code in simple service to make a test and it seems to work:

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

app.factory('Utils', function($q) {
    return {
        isImage: function(src) {
            // ... above code for isImage function
        }
    };
});

Demo: http://plnkr.co/edit/u5F6FfO3dEkNSMYV1amo?p=preview

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

6 Comments

@dfsq You isImage() has a typo; in both onerror and onload you use resolve(). First one should be reject(). Apart from that, neat solution.
@ThalisK. It's not a typo, I deliberately resolve (with false flag) in case of image unavailability, it doesn't feel to me like exceptional situation, so resolve is better. Plus for this functionality it would not be convenient to have both success and error handlers just in order to set proper flag $scope.result = result;.
@dfsq True, in your case it doesn't make sense. I was misled by my application of your answer, where the promise rejection callback does different work from the success one and it was not being called. All clear.
for those who don't know what the $q is, see: docs.angularjs.org/api/ng/service/$q
I believe this will cause a memory leak in chrome. Every image you check will create a new Image() object and this reference can hang around. See stackoverflow.com/questions/21309760/…
|
9

You can use ng-src

<img ng-src="" />

Another way is you check if the it exists using the http module.

var app = angular.module('myapp', []).run(function($http){
  $http.get('http://asd.com/asd/asd.jpg',
    //success
    function(data){

    };
});

Update:

HTML

<div ng-controller="Ctrl">
       <img ng-src="{{src}}" isImage />
</div>

JS

var app = angular.module('app', []);

app.directive('isImage', function() {
    return {
        restrict: 'A',
        link: function(scope, element, attrs) {
            element.bind('load', function() {
                alert('image is loaded');
            });
        }
    };
});

app.controller('Ctrl', function($scope) {
    $scope.src ="http://asd.com/asd/asd.jpg";
});

5 Comments

sorry i forgot to specify i do not use jQuery :) i appriciate the same, thanks
@sbaaaang: I have also mentioned the Angular way using ng-src attribute and the other way is to check via server side which you have already mentioned in your thread
i did not -1 , i gave you +1 actually, but please remove jquery part and if you can please specify how to use ng-src could be awesome !! thanks a lot
@sbaaaang: dfsq gave a better answer, i would have loved it if it was a directive.
For those with the same problem, this is a cool answer using a directive. Tested works perfectly. stackoverflow.com/a/17122325/2689390

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.