1

I am having a problem checking if a file exists using $.ajax(). I am looping through a json file with $.each and I want to see if the specified staff member has an image, and if not use the no_photo.jpg image. I keep getting the no_photo.jpg image even though there is the staff member's image in the directory.

Here is the entire $.getJSON() call.

$.getJSON('staff.json', function(data) {
                var last_check;
                var image_url = "no_photo";
              $.each(data.employees, function(i,employee){
                if ((i+1)%4==0) {last_check = " last";} else {last_check = "";}
                $.ajax({
                    url:'/images/staff/' + employee.first_name.toLowerCase() + employee.last_name.toLowerCase() + '.jpg',
                    type:'HEAD',
                    error:
                        function(){
                            image_url = "no_photo";
                        },
                    success:
                        function(){
                            image_url = employee.first_name.toLowerCase() + employee.last_name.toLowerCase();
                        }
                });
                $("div.staff-members").append('<a href="#" title="' + employee.first_name + ' ' + employee.last_name + ', ' + employee.title + '" rel="' + employee.location + '" class="' + employee.category + last_check + '"><img src="/images/staff/' + image_url + '.jpg"><span class="' + employee.category + '"></span></a>');
              });
            });
2
  • Check manually the url you are requesting in the $.ajax request and give us details on the answer. Commented Aug 22, 2010 at 22:28
  • BTW, you are making a lot of HTTP requests (1 + 2*N in the worst case), I should try to minimize them to speed up your page. Commented Aug 22, 2010 at 22:29

1 Answer 1

3

I'd strongly recommend not to use jQuerys .ajax() (or any other XHR) method for that purpose. Use Javascripts Image object instead.

var testimg = new Image();
testimg.onload = function(){
    if(this.width > 0)
       image_url = this.src;
    else
       image_url = "no_photo";

    $("div.staff-members").append('<a href="#" title="' + employee.first_name + ' ' + employee.last_name + ', ' + employee.title + '" rel="' + employee.location + '" class="' + employee.category + last_check + '"><img src="/images/staff/' + image_url + '.jpg"><span class="' + employee.category + '"></span></a>');
};
testimg.onerror = function(){
    image_url = "no_photo";
    $("div.staff-members").append('<a href="#" title="' + employee.first_name + ' ' + employee.last_name + ', ' + employee.title + '" rel="' + employee.location + '" class="' + employee.category + last_check + '"><img src="/images/staff/' + image_url + '.jpg"><span class="' + employee.category + '"></span></a>');
};
testimg.src = '/images/staff/' + employee.first_name.toLowerCase() + employee.last_name.toLowerCase() + '.jpg';

This has less overhead than an Ajax request.

update

moved the .src = instruction to the bottom (msie requires this, credits to Nick Craver)

Since this approach uses asynchronous callbacks (as does .ajax()), you need to call your .append() within the event handlers.

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

8 Comments

You would need to change your order around here, attaching an onload handler after setting the src won't fire your handler in many cases, as the event already occurred when it comes from cache.
@Nick: actually, no you don't have to do that. Well at least I never had a problem by using this order, cache or not. Can you give a usecase for your statement?
@jAndy - Sure, you can see a simple test here, try it in IE, even IE8: jsfiddle.net/nick_craver/qNFxq after the first load you won't get an alert...move the .src after the onload and you'll consistently get the alert :)
@Nick: I see, interesting. Chrome/Safari & Firefox perform as expected regardless of the order, so it seems to be another very own MSIE behavior.
@jAndy - Another thing is your answer doesn't address the async issue, image_url will still be `"no_photo" every time with your answer, it needs to actually call the append when the load or error happens :)
|

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.