Javascript every loop on JSON gets only the first element?


I'm using Jquery mobile, so ignore some of the following overdone css, its not related to the core issue.

I'm having a problem looping over the "Places" in my JSON packet/javascript object. I am getting a response with multiple "Places", but can't seem to figure out how to iterate over them. My 'i' variable in my each loop is working correctly for the first element, and displaying its corresponding name & image.

Here's my server side Django view (pretty straight-forward if your unfamiliar with Python):

def tonight_mobile(request):

    callback = request.GET.get('callback', '')

    def with_rank(rank, place):
        return (rank > 0)

    place_data = dict(
        Places = [make_mobile_place_dict(request, p) for p in Place.objects.all()]

    xml_bytes = json.dumps(place_data)
    return HttpResponse(xml_bytes, content_type='application/json; charset=utf-8')

My server is acknowledging the request and returning the following:

"GET /api/0.1/tonight-mobile.json&callback=jsonp1293142434434 HTTP/1.1" 200 167

Here's my response:

callback({"Places": [{"url": "http://localhost:8000/api/0.1/places/3.plist",
"image_url": "http://localhost:8000/static/place_logos/Bengals_1.png",
"name": "Bob's Place", "events": 2},
{"url": "http://localhost:8000/api/0.1/places/2.plist",
"image_url": "http://localhost:8000/static/place_logos/Makonde_Mask.gif",
"name": "My Bar", "events": 0},
{"url": "http://localhost:8000/api/0.1/places/1.plist",
"image_url": "http://localhost:8000/static/place_logos/Quintons_1.png",
"name": "Quinton's", "events": 1}]})


My getJSON and callback method have evolved into this:

function loadJSON(){
    $.getJSON("http://localhost:8000/api/0.1/tonight-mobile.json&callback=?", callback(data));
function callback(data){
    $("#tonight-list").each(data.Places, function(i) {
        $(this).append("<li role='option' tabindex='" + data.Places[i] + "' class='ui-li-has-thumb ui-li ui-btn ui-btn-icon-right ui-corner-top ui-corner-bottom ui-controlgroup-last ui-btn-down-c ui-btn-up-c' data-theme='c'><div class='ui-btn-inner ui-corner-top ui-corner-bottom ui-controlgroup-last'><span class='ui-icon ui-icon-arrow-r'></span><div class='ui-btn-text'><img src=" + data.Places[i].image_url + " alt=" + data.Places[i].name + " class='ui-li-thumb ui-corner-tl ui-corner-bl'/><h1 class='list-title ui-li-heading' id='list-title'><a href='detail.html?id=slide' data-transition='slide' class='ui-link-inherit'>" + data.Places[i].name + "</a></h1><span class='ui-li-count ui-btn-up-c ui-btn-corner-all'>" + data.Places[i].events + " events</span></div></div></li>");


Am I confusing how the each function iterates over the JSON (which become) Javascript objects? I am pretty sure the each is my issue here, as I am only getting the FIRST element of the "Places" list. Can someone please help me out as to how to structure the looping?

each() doesn't work that way. It takes a set of elements on the page, and loops over them, calling a function for each one. In this case, you are looping over $("#tonight-list"), which will only have one item in it (IDs are supposed to uniquely identify one element in a document).

What you seem to want to do is to loop over the data (not the #tonight-list element), and add the data to that element, right? In that case, you want normal JavaScript to do the loop, something like this:

var list = $("#tonight-list");
for (var i=0, place; place=data.Places[i]; ++i) {
    list.append("<li role='option' tabindex='" + i + "'>" + + "</li> ...etc);

Note that I have no idea if you are loading trusted data that is meant to contain HTML, untrusted plain text, etc. You may need to encode the data before inserting it or (better) insert it structurally instead of concatenating strings, depending on your use-case.