31

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.

1
  • I am not sure if ng-cloak would help you. Commented Aug 14, 2013 at 14:59

6 Answers 6

39

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

Sign up to request clarification or add additional context in comments.

3 Comments

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..
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
I think the browser will still try to load the {{path}} string it finds in <img src="{{path}}">
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.

Comments

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

Comments

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.

3 Comments

Can you set ng-src to a relative path like this: <img ng-src="/images/picture1.png">?
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.
Not trying to hijack this QA. Would you mind looking at my question? stackoverflow.com/questions/23350727/…
0

In the latest, you can evaluate it like this:

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

Comments

-3

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.