30

As explained here, the AngularJS directive ng-src is used to prevent the browser from loading the resource (e.g. image) before the handlebars get parsed. I'm currently using the following code:

<div ng-controller="MyCtrl">
  <img ng-src="http://localhost:8081/media/{{ path }}" />
</div>

With the following JavaScript:

function MyCtrl($scope, $timeout) {
    $timeout(function () {
        $scope.path = 'images/23694c70-04d7-11e3-9ba8-73fb00de24c4.png';
    }, 1000);
};

The path is being retrieved from a webservice. Because of this delay, the browser tries to load http://localhost:8081/media/, which causes a 404. Once the path is retrieved, the browser issues the correct request and loads the image.

What is the preferred method to prevent loading any resources until all data is ready?

Please see jsfiddle for an example illustrating my situation.

Dharman
  • 21,838
  • 18
  • 57
  • 107
Martijn
  • 5,021
  • 4
  • 27
  • 41

6 Answers6

38

Put the whole path inside the $scope variable. That way ng-src will wait until you provide it with the fully resolved path to the image:

<div ng-controller="MyCtrl">
  <img ng-src="{{ path }}" />
</div>
function MyCtrl($scope, $timeout) {
    var path = 'https://si0.twimg.com/profile_images/';
    $timeout(function () {
        $scope.path = path + '2149314222/square.png';
    }, 1000);
};

FIDDLE

Stewie
  • 59,860
  • 19
  • 144
  • 113
  • 6
    Thanks, that worked. Too bad angular isn't capable of evaluating the bindings within the ng-src and waiting for them to complete before loading the image.. – Martijn Aug 14 '13 at 15:03
  • 3
    Hm. If we need to pass whole path then why not to use simple `src` attribute? Anyway it will not load anything before `{{ path }}` will be present on the page – WelcomeTo Jul 08 '14 at 19:49
  • I think the browser will still try to load the {{path}} string it finds in – kevinius Feb 05 '15 at 13:21
3

Info by example


Let's take this blogitem directive. The examples above already show you how to set a default value.


HTML :

<blogitem ng-repeat="item in items" 
          bg-src="{{ item.image }}" 
          caption="{{ item.title }}"/>

JS :

.directive( 'blogitem', function()
{
    return {
        restrict    : 'E',
        templateUrl : 'js/app/directives/blogitem.html',
        replace     : true,
        // pass these two names from attrs into the template scope
        scope       : {
            intro : '@',
            bgSrc : '@'
        }
    }
} )

HTML template :

<article>
    <img ng-src="{{ bgSrc }}"/>
    <p>{{ intro }}</p>
</article>

Hopefully it helps by your understanding of the ng-src.

kaiser
  • 19,898
  • 15
  • 82
  • 102
Skid Kadda
  • 472
  • 3
  • 14
2

I hit the same issue also. One thing I noticed is that if the value for ng-src is undefined then no img is fetched. Therefore, I created a utility method to concat two arguments and return a value if and only if both arguments are defined. See below.

<div ng-controller="MyCtrl">
  <img ng-src="{{MyUtil.strConcat('http://localhost:8081/media/', path)}}" />
</div>
myApp.factory('MyUtil', function() {
    return {
        strConcat: function(str1, str2) {
            return (angular.isDefined(str1) && angular.isDefined(str2)) ? 
                (str1 + str2) : undefined;
        }
    }
});

function MyCtrl($scope, $timeout, MyUtil) {
    $scope.MyUtil = MyUtil;
...
}

FIDDLE

Amir
  • 700
  • 8
  • 18
0

You can set the ng-src to an empty string if the data has not been populated yet:

<div ng-controller="MyCtrl">
  <img data-ng-src="{{ path && 'http://localhost:8081/media/'+path || '' }}" />
</div>

when path is uninitalized, the condition would short-circuit and go to the or part and set the data-ng-src to '' (empty string), thus not hitting the server.

kumarharsh
  • 17,121
  • 7
  • 69
  • 93
  • Can you set `ng-src` to a relative path like this: ``? – Danger14 Apr 28 '14 at 20:08
  • Yes you can use. But if the string is already known, you don't need to use `ng-src`. a plain `src` would suffice. Use ng-src if you're interpolating variables into the html. – kumarharsh May 01 '14 at 05:39
  • Not trying to hijack this QA. Would you mind looking at my question? http://stackoverflow.com/questions/23350727/how-to-use-img-ng-src-in-angularjs-on-android-phone – Danger14 May 01 '14 at 21:37
0

In the latest, you can evaluate it like this:

ng-src="{{ methodThatReturnsString() }}"
-2

I am sure 100% work

First you have to make your query like this

select (select '../Images/'|| T_LANG2_NAME ||'.png' T_LANG2_NAME from T04222_T where T_LOG_ID = T04220.T_C_STATUS) TIMER from T04220 
where T_PAT_NO = '89004331' group by T_C_STATUS 
having max(T_ARRIVAL_DATE) = (select max(T_ARRIVAL_DATE) from T04220 where T_PAT_NO = '89004331');) then you write Code for Controller like this ( if (scope.T_PAT_NO) {
                debugger;
                $http({
                        method: 'POST',
                        url: '/T04205/GetTimerImage',
                        data: JSON.stringify({ PatientCode: scope.T_PAT_NO })
                    }).
                    success(function (data) {
                        debugger;
                        var newDataJSON = JSON.parse(data);

                        scope.TIMER = newDataJSON[0].TIMER;

                    });

then html code like this

<input id="imTimer" type="image" src="{{TIMER}}" style="width: 80px;height: 80px" />
Spektre
  • 41,942
  • 8
  • 91
  • 312