Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

empty ng-src doesn't update image

Tags:

angularjs

I am using the ng-src directive in order to avoid the browser to request the image before Angular evaluate the expression.

ng-src={{image}} will update the src attribute of the image if the expression "image" change. I misunderstand why the ng-src directive doesn't update the path of the image if the expression ("myImage.png") become empty ("").

When the expression become empty, the ng-src attribute become empty but the src attribute still the last known src. So it doesn't update the image. Why the src attribute isn't updated (to an empty src) so that the image "disappear".

Here is a plunker

Thanks

like image 348
gab Avatar asked Feb 28 '14 10:02

gab


4 Answers

The answer to this is in the Angular code. It's not a bug, it's just the behavior they decided they wanted. Starting on line 13895, you can see this directive code:

forEach(['src', 'srcset', 'href'], function(attrName) {
   var normalized = directiveNormalize('ng-' + attrName);
   ngAttributeAliasDirectives[normalized] = function() {
   return {
      priority: 99, // it needs to run after the attributes are interpolated
      link: function(scope, element, attr) {
          attr.$observe(normalized, function(value) {

         if (!value)
             return;

         attr.$set(attrName, value);

         if (msie) element.prop(attrName, attr[attrName]);
       });
     }
    };
  };
});

The key is in:

if (!value) return;

So as you can see, if you change the ng-src expression to an empty string, this will never change the actual src value. You can get around this doing something MadScone suggested.

like image 102
T.M. Avatar answered Oct 22 '22 02:10

T.M.


MadScone's suggestion is a cool idea, but it didn't work for me in all browsers. I ended up just showing the element only when the src isn't empty:

<img ng-show="theImage!==''" ng-src="{{theImage}}">

This seems like the safest option to me after reading through the thread that MadScone referenced (here). As a number of people pointed out there, the accepted answer doesn't work in all browsers and has some other issues that could arise. Simply hiding the element avoids all that.

Update: As enpenax pointed out in the comments, the !=='' in the ng-show is totally unnecessary. Here's the cleaner version:

<img ng-show="theImage" ng-src="{{theImage}}">
like image 27
developering Avatar answered Oct 22 '22 02:10

developering


Update (April 2015)

See developering's answer, apparently this method I suggested originally may not work in all browsers.


Original (February 2014)

I'm not fully sure why that's happening, but here's a way of solving it anyway. Add this function to your controller:

$scope.getImage = function(src) {
  if (src !== "") {
    return src;  
  } else {
   return "//:0"; 
  }
};

The "blank" image will get a source of //:0 which won't cause a missing image icon to appear (see the top answer on this thread).

Then you can set your source using:

<img ng-src="{{getImage(superImage)}}" />

EDIT:

Actually, it would be easier to change your button click to this:

<button ng-click="superImage = '//:0'">Remove superImage</button>

Then there's no need for the function. Although I think the function method is better.

like image 27
Ciarán Tobin Avatar answered Oct 22 '22 03:10

Ciarán Tobin


Another short way of solving it: <img ng-src="{{image?image:' '}}" />

like image 9
cfuglesang Avatar answered Oct 22 '22 04:10

cfuglesang