1

I want to display a user profile image if it exists; else show default font awesome icon. The profile picture name is an unique number and the extensions can be of following types (jpg, jpeg, png, gif and etc).

What i have done so far

<div ng-repeat="user in users">
    <p> {{user.name}} </p>
    <img ng-src="{{('/media/upload/' + user.id + '.jpg')}}" onerror="this.src='/media/upload/default.jpeg'" height="80px" width="80px"/>
</div>

Right now it only shows image with an ext .jpg.

How can i create a custom filter to check if image is available in following extensions (jpg, jpeg, png, gif)and show font awesome icon if it doesn't?

Any help and feedback are appreciated!

Thanks!

MysticCodes
  • 3,092
  • 5
  • 25
  • 33
  • This might help: http://stackoverflow.com/questions/22423057/angular-js-isimage-check-if-its-image-by-url – jesusr Apr 25 '16 at 13:19

1 Answers1

-1

You don't need any filter in order to achieve that, just make a default src:

<img ng-src="{{('/media/upload/' + user.id + '.jpg')}}" src="/media/upload/default.jpeg" height="80px" width="80px"/>

The ngSrc directive whould replace the source only if available

In order to test all possible extensions, I would write a directive:

app.directive('multiSrc', function($q) {
  return {
    restrict: 'A',
    scope: { user: '=' },
    link: function(scope, element) {

      console.log(scope.user);

      var image = new Image();
      var _ext = ['jpg', 'jpeg', 'png', 'gif'];
      function _loadExt(index) {
        if(index >= _ext.length) {
          return;
        }
        _tryLoading(_ext[index])
        .then(function(successImage) {
          element[0].src = successImage.src;
        }, function() {
         return _loadExt(index + 1);
        });
      }
      function _tryLoading(extension) {
        var _defer = $q.defer();
        image.src = '/media/upload/' + scope.user.id + '.' + extension;
        image.onerror = function() {
          _defer.reject();
        };
        image.onload = function() {
          _defer.resolve(angular.copy(image));
        }
        return _defer.promise;
      }
      return _loadExt(0);
   }
 };
});

Edit

This is showing one way to implement it. But it IS NOT best practice at all.

The way this should be done, is when the user upload an image, save the path in the database (within the user object usually), then just request the registered path.

Kobi Cohen
  • 678
  • 4
  • 9
  • 1
    Well you're repeating me! How can i check if image exist in extensions such as: jpg, jpeg, png, gif and etc? The default src is not an optimal solutions! – MysticCodes Apr 25 '16 at 13:27
  • Thanks Kobi! How to use this directive in template? – MysticCodes Apr 26 '16 at 11:39
  • `+ scope.user.id +` can't read property of undefined! Pretty close! Thanks @Kobi Cohen – MysticCodes Apr 27 '16 at 06:33
  • I don't know why it's undefined, here is a working plunkr https://embed.plnkr.co/hbMprRxYk8xCdgeSAvjH/. also, I've edited the answer after debugging the code. take a look – Kobi Cohen Apr 27 '16 at 07:57
  • you have created `$scope.user = {id: '4656543'}` in controller, but in my case the `user.id` comes from template. How can i pass user.id as an argument from template to directory? – MysticCodes Apr 27 '16 at 09:07
  • It doesn't make any difference. you have the users array in the controller, right? updated the plunkr – Kobi Cohen Apr 27 '16 at 12:43
  • Thanks Kobin! One thing i realised is that when image doesn't exist then it send multiple request for image with different extensions. http://tinypic.com/r/2rms7m0/9. Is there way to minimise number of requests? – MysticCodes Apr 27 '16 at 13:18
  • I don't think so. If you want to check that image exist then you have to send request for every extension. see the updated answer – Kobi Cohen Apr 27 '16 at 14:02
  • The approach you mentioned (saving image path in db) sounds promising – MysticCodes Apr 29 '16 at 12:51