0

I have the following code which is included in a keypress function:

$.getJSON('dimensions.json', function(data) {
    $.each(data, function(index) {
        $('#div1').append(index);
    });
});

I'm trying to first get the JSON string, save it in a variable and then run the each(). I want to basically separate the each() to be unlinked to the getJSON() function because I don't want it to fetch the json file for every keypress.

I've tried this, but it didn't work:

var JSONstr = $.getJSON('dimensions.json');
$.each(JSONstr, function(index) {
    $('#div1').append(index);
});
12
  • 1
    Have you compared console.log(data) and console.log(JSONstr) ? Commented Jan 7, 2012 at 23:37
  • Why do you want to do that? (You can't, is why I ask.) Commented Jan 7, 2012 at 23:38
  • @Pointy - The first code snippet is included within a 'keypress' function, so at the moment every time a key is pressed, my script is fetching the json file. I wanted to fetch it once to a var and then run the keypress function on the var. Commented Jan 7, 2012 at 23:40
  • The problem is that you can't be sure that the variable's value is available until the callback to the $.getJSON. What you could do is defer binding of the "keypress" handler to inside that callback as well. Commented Jan 7, 2012 at 23:48
  • @hoverhand please edit your question with this extra information, it's not obvious what you mean at first. (I'm editing my answer) Commented Jan 7, 2012 at 23:52

2 Answers 2

2

In your first example, you do $.each in the callback. The callback is executed by some other callback after there result is received, while $.getJSON returns immediately without waiting for the result (since there is no blocking in JavaScript by design).

Therefore the code in your second example can never work: the $.each begins before any result is received from the web server, probably even before the request is sent. Whatever the return value of $.getJSON is, it can't, by the design of JavaScript, be the result of AJAX request.

UPD: Saw your comment, now I understand what you wanted to do. Here's a simple example of how to do this:

function ActualHandler(data) {
    $.each(data, function(index) {
        $('#div1').append(index);
    });
}

function KeypressHandler() {
    if (window.my_data) { // If we have the data saved, work with it
        ActualHandler(window.my_data);
    }
    else { // Otherwise, send the request, wait for the answer, then do something
        $.getJSON('dimensions.json', function(data) {
             window.my_data = data; // Save the data
             ActualHandler(data); // And *then* work on it
        });
    }
}

Here, the ActualHandler is not launched before the data is received, and once that happens, all subsequent clicks will be handled immediately.

The downside in this particular case is that if user clicks again while the first request is running, one more will be sent. But to fix that you would need to maintain some queue, which is kind of out of scope here.

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

3 Comments

He wants the $.each() to run outside of the $.getJSON() callback.
Maybe you could save the JSON data in a variable and then run HandleJSON with that variable onkeypress?
Exactly what my code does, no? Except for the first time, when the only alternatives to run it "outside" of callback is a) inside of setInterval callback b) not running it at all c) running it without any data. None of these look like a solution me.
0

You fell into the asynchronous trap. Your $.each() function doesn't wait for your $.getJSON() call to get the data. You can get around this by using the good 'ol $.ajax() function. Like this:

function processJSON(data) {
    $.each(data, function(index) {
        $('#div1').append(index);
    });
}

$.ajax({
    url: 'dimensions.json',
    dataType: 'json',
    async: false,
    success: processJSON(data)
});

1 Comment

But this doesn't separate between the each and the file being fetched

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.