2

I have this code below, which is supposed to return the result of the call. I need to do this synchronously so that I know everything is good, however it doesn't seem to work. What am I doing wrong?

/* jQuery library:
 * http://code.jquery.com/jquery-1.9.1.min.js
 */
function getJSON(url){
    var result;
    $.getJSON(url, { async: false, success: function(data) {
        result = data;
        alert(data); // **Edit**: also undefined
    }});
    alert(result); // undefined
    return result;
}
Arlen Beiler
  • 15,336
  • 34
  • 92
  • 135
  • jsonp? This is the code I am using. – Arlen Beiler Mar 07 '13 at 22:17
  • Would you mind telling us what your url is (or is like)? – Benjamin Gruenbaum Mar 07 '13 at 22:17
  • 1
    the data parameter of getJSON is for sending data to the server, not setting parameters. And even then, you're using it wrong. Why do you want to make it `async: false`? that's a terrible idea unless you're in a webworker. – Kevin B Mar 07 '13 at 22:17
  • 1
    possible duplicate of [Is it possible to set async:false to $.getJSON call](http://stackoverflow.com/questions/2765411/is-it-possible-to-set-asyncfalse-to-getjson-call) – Garis M Suero Mar 07 '13 at 22:18

4 Answers4

11

getJSON does not honor async:false

getJSON has no async: false option. You'd have to use ajax for that.

According to the documentation, getJSON is equivalent to:

$.ajax({
  dataType: "json",
  url: url,
  data: data,
  success: success
});

...to which you can easily add an async: false option (for now, be forewarned that jQuery will be dropping support for that).

I need to do this synchronously so that I know everything is good

You don't need to do anything synchronously to "know everything is good", it's perfectly possible (and normal) to handle results (whether "good" or errors) asynchronously.


In the comments on your question, you've written:

jsonp? This is the code I am using.

JSON-P is not the same as JSON (and getJSON doesn't do JSON-P unless you have callback=? or similar in the URL), and JSON-P is inherently asynchronous. Unlike a true ajax call via XMLHttpRequest, it's impossible to make JSON-P synchronous.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • This is NOT quite right. `$.getJSON()` uses `$.ajax()` internally. – jfriend00 Mar 07 '13 at 22:21
  • @jfriend00: What part is not right? `getJSON` has no `async: false` option. If you want to use that option, you have to call `ajax` directly. – T.J. Crowder Mar 07 '13 at 22:22
  • The part that's not right is that you can't solve the problem by using `$.ajax()` either. You CAN'T do cross domain JSON requests with `$.ajax()` either. So your recommendation to use `$.ajax()` isn't right. – jfriend00 Mar 07 '13 at 22:23
  • 3
    @jfriend00: I never said you could (although you're actually incorrect there: you *can* do cross-domain synchronous requests, via [CORS](http://www.w3.org/TR/access-control/); just not via JSON-P). I said you could set `async: false` by using `ajax` directly. I didn't say anything about cross-domains requests. I'd appreciate it if you'd have a read-through again before giving me a hard time. :-) If that's your downvote, with respect, I have to say, that's pretty surprising. – T.J. Crowder Mar 07 '13 at 22:24
2

$.getJSON() does not support async: false and there is no way to even pass that option to $.getJSON() (look at the arguments in the jQuery doc).

Internally, $.getJSON() uses $.ajax() and if you look at the doc page for $.ajax(), it tells you right there that if the ajax request is cross domain and it's for JSONP, it does not support async: false.

The reason for this is that a cross domain JSON request is implemented with JSONP which by definition a dynamically inserted <script> tag which can only be asynchronous. It cannot be synchronous.

You will need to code your request to be asynchronous if it is cross domain or use $.ajax() directly if it is not cross domain.

jfriend00
  • 683,504
  • 96
  • 985
  • 979
1

I just insert this code before getJSON:

$.ajaxSetup({
    async: false
});

Original answer: Is it possible to set async:false to $.getJSON call

0

$.getJSON is a shorthand for $.ajax.

This is a shorthand Ajax function, which is equivalent to:

$.ajax({ dataType: "json", url: url, data: data, success: success });

You'll notice that there is no option for passing through an async option. The parameter you are attempting to add async: false to is actually the data that will be sent to the url with the ajax request.

Try doing this instead:

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

Also, your statement

I need to do this synchronously so that I know everything is good

is incorrect. You can 'know everything is good' from the asynchronous callback. Your sample code would do what you are trying to do above exactly if you wrote it like this:

function getJSON(url){
    var result;
    $.getJSON(url, function(data) {
        alert(data);
        // do other stuff with data, call other methods etc. etc.
    });
}

You could even define your callback function separately and pass it to $.getJSON, like so:

function jsonCallback(data) {
    alert(data);
    // do other stuff with data, call other methods etc. etc.
} 
function getJSON(url){
    var result;
    $.getJSON(url, jsonCallback);
}
Patrick M
  • 10,547
  • 9
  • 68
  • 101
  • "...above exactly if you wrote it like this:" But when would result get set and returned? – Arlen Beiler Mar 07 '13 at 22:25
  • You don't need to set it or return it to use it. Whatever else you want to do with it, just do it in the callback. If you want to cache it or hold on to it, you could store it on the window (globally) by doing `window.lastJsonResult = data;`, but that works just as well asynchronously. The only thing you gain by insisting that it be synchronous is that the entire system locks up while you're waiting, and most people would consider that a drawback, not a plus. – Patrick M Mar 07 '13 at 22:30