Paul Erdos
Paul Erdos

Reputation: 1375

How to access src attribute within Angular directive when using ng-src

I have the following HTML (inside a gsp):

<img ng-src="${resource(dir: '')}/images/stores/closeBTN.svg" />

I want to use Modernizr to detect whether or not SVG is supported, and switch the image to a png if it's not. I've adapted this directive: https://github.com/tinacious/angular-svg-png

angular.module('svgPng', [])
  .directive('img', function () {
    return {
      restrict: 'E',
      link: function (scope, elem, attrs) {
        if ( typeof Modernizr !== 'undefined' && !Modernizr.svg ) {
          elem.attr('src', attrs.src.replace('.svg', '.png'));
        }
      }
    };
  });

The problem is that attrs.src is undefined, so the replace doesn't work. I know that ng-src should populate the src, so do I need to force a digest loop or something to make src defined?

Upvotes: 3

Views: 1238

Answers (1)

PSL
PSL

Reputation: 123739

You are doing it too early before the digest cycle, which processes ng-src and adds src attribute. So let the digest cycle happen, you can make sure of it by placing this in $timeout or use setTimeout.

 .directive('img', function () {
    return {
      restrict: 'E',
      link: function (scope, elem, attrs) {
        if ( typeof Modernizr !== 'undefined' && !Modernizr.svg ) {
         $timeout(function(){
            elem.attr('src', attrs.src.replace('.svg', '.png'));
         }, false);
        }
      }
    };
  });

Or a better bet would be t do the replacement too early before ngSrc has a chance to even process it. Use the compile function to replace the extension in ng-src attribute's value, and also this prevent both the images to be loaded as it would happen in the previous case (one with .svg and one with .png).

 .directive('img', function () {
        return {
          restrict: 'E',
          compile: function (elem, attrs) {
            if ( typeof Modernizr !== 'undefined' && !Modernizr.svg ) {
               attrs.$set('ngSrc', attrs.ngSrc.replace('.svg', '.png'));
            }
          }
      };
 });

Upvotes: 2

Related Questions