0

I understand how $.get() fetches asynchronously. But how can I force a synchronous call?

I require preferences loaded from a json file to be used throughout many javascript calls throughout an app. How can I load these preferences not into the DOM, but rather a variable to be used throughout the rest of the app?

Here's how it works asynchronously:

$.get('my.json',function(data) { var myJson = data; });
console.log(myJson); // undefined
$('.myElement').html(myJson.title); // this will asynchronously load the contents of myJson.title into `.myElement`

I've read that I should try:

$.get('my.json',WrapperFunction(data));
WrapperFunction(data) {
    // do all of your javascript calls here
}
console.log(myJson); // undefined

Any other ideas to not move on until get completes?

Ryan
  • 14,682
  • 32
  • 106
  • 179
  • 1
    Try using `$.ajax()` instead of `$.get()`. You can use the `async` flag and set it to `false`. – Patrick Q Mar 13 '14 at 19:03
  • `$.get` is just a shortcut for `$.ajax`, so use `$.ajax` instead. But better move all the code that needs access to the data *inside* the callback: `$.get('my.json',function(data) { var myJson = data; console.log(myJson); $('.myElement').html(myJson.title); });` – Felix Kling Mar 13 '14 at 19:03
  • 3
    Please don't recommend that people set `async` to false. Not only has this been depreciated in recent versions of jQuery, its also a *Bad Item* (tm). There is a reason why async is the default. – Jeremy J Starcher Mar 13 '14 at 19:05
  • You can use the deferred/promise api to have the logic appear later in your source code, but you really shouldn't make it synchronous – JoseM Mar 13 '14 at 19:05
  • and (worse) [How can I get jQuery to perform a synchronous, rather than asynchronous, AJAX request?](http://stackoverflow.com/q/133310/218196) – Felix Kling Mar 13 '14 at 19:06
  • 1
    @JeremyJStarcher: To be fair, only the usage of `async` *together* with the promise API is deprecated: *"As of jQuery 1.8, the use of async: false with jqXHR ($.Deferred) is deprecated;"*. (that doesn't mean I'm advocating the use of `async`). – Felix Kling Mar 13 '14 at 19:08
  • @FelixKling Thanks for the clarification. I must have misread the spec when scanning. – Jeremy J Starcher Mar 13 '14 at 19:09
  • @Ryan, Why do you need this to be synchronous? – Kevin B Mar 13 '14 at 19:10
  • It doesn't, I've restructured my code to run everything else inside the callback of the get. – Ryan Mar 13 '14 at 21:20

3 Answers3

1

Example from the docs:

$.get( "my.json", function( data ) {
  console.log( data );
  var myJson = data;  // or whatever your data's format is
  console.log( "Title: " + myJson.title );
  $('.myElement').html( myJson.title ); // or whatever your data's format is
});

notice the console is inside the function() instead of outside as you had it.

updated example

blurfus
  • 13,485
  • 8
  • 55
  • 61
  • Yes, but assume the rest of the document (i.e. outside the `get`) will need the `data` right away. – Ryan Mar 13 '14 at 19:06
  • 2
    @Ryan - It can't have it right away. if there is something that the page needs to have at page load, include it on the page itself. You can embed a JavaScript object on your page from your server-side processing. – Jeremy J Starcher Mar 13 '14 at 19:08
  • @Ryan: That's why you execute the rest of your code from inside the callback. JavaScript is inherently event driven. – Felix Kling Mar 13 '14 at 19:08
  • forcing .get() to be synchronous is not a good idea IMHO. Do you really need the call to be synchronous? or do you just need to ensure the data is returned from the server before you execute the next step? – blurfus Mar 13 '14 at 19:17
1
  1. You need to declare your myJson var outside the function scope function(data) { var myJson = data; }); or else it will not be visible to other functions.

    var myJson; $.get(...);

  2. Synchronous ajax calls are bad. You don't need that. All you need is that when the data is available to notify other parts of your app.

var myJson;
$.get('url.json', function(data){
    myJson = data;
    dataIsAvailable();
});

function dataIsAvailable() {
 ... you can use myJson here
}
kcsoft
  • 2,917
  • 19
  • 14
0

You are declaring your variable in the wrong place. If you want the variable to be available to multiple functions you have to declare it outside of those functions. You don't need to run the request synchronously to achieve what you want.

var mySettings;

$.get('my.json',function(data) { mySettings = data; });

function showSettings() {
    alert(mySettings);
}
ZippyV
  • 12,540
  • 3
  • 37
  • 52