empty ng-src doesn't update image

Solution 1:

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.

Solution 2:

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}}">

Solution 3:

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.

Solution 4:

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