0

I have a function that, right now, retrieves a JSON file via AJAX call and prints out its contents on the console. However, I can't get it to read the file. I know that the location is formatted correctly, but the json variable will always return a value of null, indicating a nonexistent file.

function loadSettings(){
    //loads setting list from mcc.json
    var options = (function() {
        var json = null;
        $.ajax({
            'async': false,
            'global': false,
            'url': "js/mcc.json",
            'dataType': "json",
            'success': function (data) {
                json = data;
            }
        });
        return json;
    })();
    console.log(options);
}

Did I do something wrong with my AJAX call?

Thassa
  • 532
  • 8
  • 27
  • if you are grabbing it from your file system, why not use ES6 `import` and `export`? – Christian4423 Jul 11 '17 at 16:42
  • Since AJAX is async, although you have property async, which will only do async when there are multiple ajax calls in the server. The above code will return json as soon as the ajax call is done. – ashish Jul 11 '17 at 17:12
  • Possible duplicate of [Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference](https://stackoverflow.com/questions/23667086/why-is-my-variable-unaltered-after-i-modify-it-inside-of-a-function-asynchron) – Heretic Monkey Jul 11 '17 at 17:59

4 Answers4

2

The success/complete callback occurs only when the ajax call is completed. So nothing is actually being returned by your function ("return json").

In AJAX, you need to get the data object, then call what should run next, because any success or complete callback functions will happen AFTER the code you're executing, when the response from the server comes back.

Basically, you are returning the json variable, before the ajax call completes.

  • So what should the AJAX call look like, then? I understand what's going on, but I'm not sure how to format it correctly. – Thassa Jul 11 '17 at 16:47
  • The are several way, but my prefered is to reestructure your code. Create a function with the name mycallback();, an on success/complete of your ajax function call your function called mycallback(); . Check out this link http://node-tricks.com/return-response-ajax-call/ – Endika Ramos Jul 11 '17 at 16:53
  • That article helped. I was able to remake my function to call another callback function. – Thassa Jul 11 '17 at 18:25
0

AJAX is an async call by it's name itself, so it is a non blocking code, so your

return json will be immediately (which you assigned to null), after some time when the response came back from server the success callback will be executed, which still has a access to the variable (json) declared in the outer closure.

instead try returning a promise, and resolve that promise when data came in success callback. and in the use end of the promise, use then with a callback to get the data when its resolved with the data.

EDIT

Here in edit, I am editing your code and adding to this answer, to use a promise and immediately return the promise in order to work it with the same pattern

function loadSettings(){
    //loads setting list from mcc.json
    var options = (function() {
        var defer= $.Deferred(); // create a deferred-promise 
        $.ajax({
            'async': false,
            'global': false,
            'url': "js/mcc.json",
            'dataType': "json",
            'success': function (data) {
                defer.resolve(data);
            }
        });
        return defer.promise(); // return the deferred promise instead
    })();
    options.then(function(data){
        console.log(data);
    }); 
}
Koushik Chatterjee
  • 4,106
  • 3
  • 18
  • 32
0

Since you're assigning to options the returned value from an immediately invoked function, you should bare in mind that javascript won't stop its execution or wait for any async request to be resolved thus your IIFE will return right away (in your case, with json set to null)

if you need to process the returned data, do it within the success callback

taha
  • 997
  • 9
  • 17
0

The AJAX call has not completed when you return your JSON Data. Someone mentioned using a promise, but the alternative is shown below. This calls doTheNextThing function after the AJAX completes. Handle your settings in that new function.

function loadSettings(){
    var options = (function() {
        $.ajax({
            'async': false,
            'global': false,
            'url': "js/mcc.json",
            'dataType': "json",
            'success': function (data) {                
                doTheNextThing(data);
            }
        });           
    })();
}
//------------------------------------------
function doTheNextThing(data)
{
    //Now process your load settings here
}
Elim Garak
  • 1,728
  • 1
  • 16
  • 21