3

I'm working on my collage project (Web app written in C#) and I'm using javascript to dynamically add hotels with details and image using following code:

$.ajax({
    type: 'POST',
    url: 'WebServiceBooking.asmx/Hotels',
    data: "{'stars':'" + stars + "','countryid':'" + country + "'}",
    contentType: "application/json; charset=utf-8",
    dataType: "json",
    success: function (data) {
        $('.hotels').empty();
        var hotels = data.d; //getting List<Hotel> from [WebMethod](works)
        window.t = "";
        window.ImageID = "";
        $.each(hotels, function (index, hotel) {
            $.ajax({ //this ajax is getting Image for specified hotel.HotelID
                type: 'POST',
                url: 'WebServiceBooking.asmx/HotelImage',
                data: "{'hotelid':'" + hotel.HotelID + "'}",
                contentType: "application/json; charset=utf-8",
                dataType: "json",
                success: function (data) {
                    window.ImageID = data.d;
                    //$('.hotels-image').attr('src', 'ImageHandlerFromID.ashx?ImageID=' + data.d);
                },
                complete: function (xhr, status) {
                    window.t += "<div class='hotel clearfix'><h3><a href='hotel.aspx?HotelID=" + hotel.HotelID + "'>" + hotel.HotelName + "</a></h3><p class='hotelAddress'>" + hotel.HotelAddress + "</p><p class='hotelPhone'>" + hotel.HotelPhone + "</p>";
                    window.t += "<img class='hotels-image' src='ImageHandlerFromID.ashx?ImageID=" + window.ImageID + "'/>";
                    window.t += "</div>";
                    console.log(window.ImageID);
                }
            });

            console.log(ImageID);
        });
        console.log(window.t);
    },
    complete: function (xhr, status) {
        $('.hotels').append(window.t);
    }
});

After several attempts, neither complete function works.

Mark Schultheiss
  • 32,614
  • 12
  • 69
  • 100
NikolaTasic
  • 41
  • 1
  • 5
  • You forgot to explain what the problem is! What is the code supposed to do? What's it actually doing? Do you see any errors? – bfavaretto Sep 17 '13 at 20:56
  • 1
    Welcome to the wonderful world of **async**! You need to wait for it to finish. – SLaks Sep 17 '13 at 20:56
  • 1
    Ajax is async. The `complete` callback for the outer ajax call executes before the `complete` callbacks for the inner ajax calls. – Jason P Sep 17 '13 at 20:57
  • @bfavaretto no errors shown in console, it reports all values right it just doesnt append in $('.hotels').append(window.t); – NikolaTasic Sep 17 '13 at 20:58
  • @JasonP how is that posible when inner Ajax is called before outer Ajax complete callback? – NikolaTasic Sep 17 '13 at 21:02
  • The inner callback is _specified_ before the outer callback executes, but are _executed_ after. Read [this question and answer](http://stackoverflow.com/questions/14220321/how-to-return-the-response-from-an-ajax-call) and try to understand the nature of async and when callbacks are actually executed. – Jason P Sep 17 '13 at 21:05
  • thx for help...i solved it by adding async:false in inner one... – NikolaTasic Sep 17 '13 at 21:13
  • I strongly urge you to reconsider. That is the worst possible solution. – Jason P Sep 17 '13 at 21:17
  • Do you control the app that provide the data? If so, why not have it send all of the necessary info about the hotels and prevent the need for all those extra (and most likely time consuming) AJAX calls? – MasterAM Sep 17 '13 at 21:20
  • @MasterAM yes i do and what is the best way to return 2 list<> items from webmethod then? – NikolaTasic Sep 18 '13 at 21:14

1 Answers1

0

The complete call will only complete the first ajax call. Not the one's in the for loop. If you want to check if all requests are done use $.when.

var requests = [];
var overall_data = {"hotels" = [], "hotel_images" = []}
var main_request = $.ajax({
  type: 'POST',
  url: 'WebServiceBooking.asmx/Hotels',
  data: "{'stars':'" + stars + "','countryid':'" + country + "'}",
  contentType: "application/json; charset=utf-8",
  dataType: "json",
  success: function (data) {
    $('.hotels').empty();
    var hotels = data.d; //getting List<Hotel> from [WebMethod](works)
    overall_data["hotels"] = hotels
    window.t = "";
    window.ImageID = "";
    $.each(hotels, function (index, hotel) {
        var hotel_request = $.ajax({ //this ajax is getting Image for specified hotel.HotelID
            type: 'POST',
            url: 'WebServiceBooking.asmx/HotelImage',
            data: "{'hotelid':'" + hotel.HotelID + "'}",
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            success: function (data) {
                window.ImageID = data.d;
                overall_data["hotel_images"].push(data)
                //$('.hotels-image').attr('src', 'ImageHandlerFromID.ashx?ImageID=' + data.d);
            }
        });
        requests.push(hotel_request)
        console.log(ImageID);
    });
    console.log(window.t);
  }
});

requests.push(main_request);

$.when.apply(null, requests).done(function(){
// Do your stuff with overall_data
})
Biketire
  • 2,019
  • 1
  • 23
  • 41