0

I am studying javascript and json but every line of code I write is another problem. I've done a script that works with json but I'm a beginner and the performances of what I wrote aren't that good. The code works only if I do a debug step by step with firebug or other tools and that makes me think that the execution of the code (or a part of it ... the one that creates the table as you'll see) requires too much time so the browser stops it.

My code is:

var arrayCarte = [];
var arrayEntita = [];
var arraycardbyuser = [];

function displayArrayCards() {
    var richiestaEntity = new XMLHttpRequest();

    richiestaEntity.onreadystatechange = function() {
        if(richiestaEntity.readyState == 4) {
            var objectentityjson = {};
            objectentityjson = JSON.parse(richiestaEntity.responseText);

            arrayEntita = objectentityjson.cards;
        }
    }
    richiestaEntity.open("GET", "danielericerca.json", true);
    richiestaEntity.send(null);

    for(i = 0; i < arrayEntita.length; i++) {

        var vanityurla = arrayEntita[i].vanity_urls[0] + ".json";
        var urlrichiesta = "http://m.airpim.com/public/vurl/";

        var richiestaCards = new XMLHttpRequest();
        richiestaCards.onreadystatechange = function() {
            if(richiestaCards.readyState == 4) {
                var objectcardjson = {};
                objectcardjson = JSON.parse(richiestaCards.responseText);


                for(j = 0; j < objectcardjson.cards.length; j++)
                arrayCarte[j] = objectcardjson.cards[j].__guid__; //vettore che contiene i guid delle card

                arraycardbyuser[i] = arrayCarte;

                arrayCarte = [];
            }
        }
        richiestaCards.open("GET", vanityurla, true);
        richiestaCards.send(null);
    }





    var wrapper = document.getElementById('contenitoro');

    wrapper.innerHTML = "";

    var userTable = document.createElement('table');

    for(u = 0; u < arrayEntita.length; u++) {
        var userTr = document.createElement('tr');

        var userTdcard = document.createElement('td');
        var userTdinfo = document.createElement('td');

        var br = document.createElement('br');

        for(c = 0; c < arraycardbyuser[u].length; c++) {
            var cardImg = document.createElement('img');
            cardImg.src = "http://www.airpim.com/png/public/card/" + arraycardbyuser[u][c] + "?width=292";
            cardImg.id = "immaginecard";
            userTdcard.appendChild(br);
            userTdcard.appendChild(cardImg);

        }

        var userdivNome = document.createElement('div');
        userdivNome.id = "diverso";
        userTdinfo.appendChild(userdivNome);

        var userdivVanity = document.createElement('div');
        userdivVanity.id = "diverso";
        userTdinfo.appendChild(userdivVanity);

        var nome = "Nome: ";
        var vanityurl = "Vanity Url: ";
        userdivNome.innerHTML = nome + arrayEntita[u].__title__;
        userdivVanity.innerHTML = vanityurl + arrayEntita[u].vanity_urls[0];

        userTr.appendChild(userTdcard);
        userTr.appendChild(userTdinfo);
        userTable.appendChild(userTr);
    }

    wrapper.appendChild(userTable);
}

How can I solve this problem?

8
  • 3
    Using jQuery would simplify a lot of this for you. Commented Jun 27, 2012 at 14:32
  • 1
    And so would indenting the code properly. Commented Jun 27, 2012 at 14:33
  • 1
    @GabrielButoeru yes, async is good. But you also need the second one to finish before you can do everything else. Commented Jun 27, 2012 at 15:05
  • 1
    that's right - you can't make the table until the asynchronous requests have finished. Commented Jun 27, 2012 at 15:20
  • 1
    only if you've only got one card. You have a loop which suggests otherwise, so you can't build your table until they've all completed. Commented Jun 27, 2012 at 15:28

1 Answer 1

1

You've created a race condition (of sorts) - you're not waiting until the AJAX has been parsed and for your data to have been written into the right variables before proceeding with the rest of your page logic.

When you run it in the debugger you end up giving your code enough time to complete the AJAX request before trying to use the variables that you populate in your onstatechange handler.

This code would be much easier with jQuery and deferred objects:

var arrayCarte, arrayEntita, arraycardbyuser;

// do first seeding request
var req1 = $.ajax(...);

var req2 = [];
req1.done(function(objectentityjson) {

    arrayEntita = objectentityjson.cards;

    // initiate the inner AJAX requests
    for (var i = 0; i < arrayEntita.length; ++i) {

        var tmp = $.ajax(...);
        tmp.done(function(objectcardjson) {
            // process the sub data here
            ...
        });

        req2.push(tmp);  // keep the object around for later sync-up
    }
});

// this'll only fire when all of the inner AJAX requests have completed
$.when.apply($, req2).done(function() {
     // do the rest of your page setup here
     ...
});
Sign up to request clarification or add additional context in comments.

4 Comments

it's the code after that's the problem (starting at var wrapper = ... - you have nothing to prevent this code from running until after the AJAX requests have completed.
so how can I fix it? sorry but I'm a beginner (n00b)
@GabrielButoeru given you're sending multiple AJAX requests, and you apparently need all of them to be answered before you proceed, I'd very strongly recommend jQuery and also its "deferred object" features. Those make it easy to trigger a callback only when a whole set of async calls have completed.
I don't understand how to work with callbacks (this is my second week of javascript studying): I'm looking how it works right now but sadly I can't understand much of what I'm reading.

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.