0

I have a stringified array of objects in a database that I'm retreiving with an $.ajax call. I'm trying to use a callback function to get that data into an array outside of my ajax function.

function getMap(){
    return $.ajax({
    url: "getMap.php",
    type: "POST",
    data: "",
    dataType: 'JSON',
    success: dataHandler
    });
};
function dataHandler(data){
    console.log(JSON.parse(data));
    return JSON.parse(data);
}

var loadedMap = getMap();
console.log(loadedMap);

The console.log inside of the dataHandler function shows up in my Javascript console as a standard Array (clickable, can view all the data). The console.log at the very end shows up in the console as [object Object]. I can see the actual data inside of that object in a "responseJSON" field, but I can't seem to correctly get that into the loadedMap array.

What am I missing here?

Edit: I feel like my question is different from all of the answers to other questions. Mine seems to be more of a scope problem. A lot of the answers advocated the .done and .fail ways to handle AJAX.

var loadedMap = [];
function getMap(){
    return $.ajax({
    url: "getMap.php",
    type: "POST",
    dataType: 'JSON',
    });
};
getMap().done(function(r) {
    if (r) {
       loadedMap = r;
    } else {
       console.log("No data");
    }
}).fail(function(x) {
    console.log("error");
});
console.log(loadedMap);

This code successfully gets the array where "loadedMap = r", but when you console.log the loadedMap on the outside, its undefined. How can we get the actual data to be outside the AJAX functions?

bo_knows
  • 856
  • 2
  • 9
  • 20
  • can you show how responseJSON looks like? – Vlas Bashynskyi Jul 02 '14 at 19:44
  • LoadedMap is not an array, its the ajax you are making. You need to work inside your dataHandler function to have the json data or call another function from there – juvian Jul 02 '14 at 19:46
  • VLAS: "[[{"type":"land"},{"type":"grass"},{"type":"mountains"},{"type":"water"},{"type":"water"}],[{"type":"land"},{"type":"land"},{"type":"grass"},{"type":"land"},{"type":"mountains"}]]" an array of objects – bo_knows Jul 02 '14 at 19:52
  • 1
    By specifying `dataType: 'json'` (note: should be lowercase), jQuery will already attempt to parse the response (and, `error` when it fails to parse). `data` is likely already a JavaScript `Array` and using `JSON.parse(data)` is likely redundant. Also, [How to return the response from an Ajax call?](http://stackoverflow.com/questions/14220321/how-to-return-the-response-from-an-ajax-call) – Jonathan Lonowski Jul 02 '14 at 19:54
  • I don't think this is exactly like the other answers. My question is more about scope and none of the answers on that page address getting the data outside the AJAX function. I edited above to show a psuedo answer, but my scope problem still exists. – bo_knows Jul 02 '14 at 21:57
  • 1
    @bo_knows The problem isn't scope, it's the timing of execution. `$.ajax()` is asynchronous, which means "*not at the same time*" and that the code will execute in separate parts -- 1) `getMap()` and `console.log(loadedMap)`, then 2) `function(r)` and `loadedMap = r;`, resulting in `loadedMap` being assigned the intended value after it's being logged. – Jonathan Lonowski Jul 02 '14 at 22:26
  • What's the synchronous version of a db call then? I only tried Ajax because I was sort of familiar from another project/experiment – bo_knows Jul 02 '14 at 23:01

2 Answers2

0

The function getMap does not return the response, it just calls dataHandler when the response arrives. create a global variable and assign the vallue of the JSON.parse(data) to that variable. :

    var myData;
    function getMap(){
...
    });
    };
    function dataHandler(data){
        console.log(JSON.parse(data));
        myData = JSON.parse(data);
    }
getMap();
Vlas Bashynskyi
  • 1,886
  • 2
  • 16
  • 25
0

JQuery's AJAX returns a promise, so you can either go the callback route, as it looks like you were trying to do, or you can simplify it with promises:

function getMap(){
    return $.ajax({
    url: "getMap.php",
    type: "POST",
    data: "",
    dataType: 'JSON',
    success: dataHandler
    });
};

getMap().then(function(data){
    loadedMap = JSON.parse(data);
    console.log(loadedMap);
});
Andrew McGivery
  • 1,350
  • 8
  • 20
  • This works, however the scope of loadedMap is now inside of the then(function(data)) call. Doing the console.log after it, yields an undefined error. – bo_knows Jul 02 '14 at 20:00
  • That's kind of the nature of AJAX, which is event driven. In the background, behind the JQuery, is a XmlHttpRequest which has an onload event call. You're going to end up with the response in an enclosed scope regardless of how you do it. – Andrew McGivery Jul 02 '14 at 20:08
  • Is there any way around this? I feel like my question is less an AJAX question and more a scope one. – bo_knows Jul 02 '14 at 21:53
  • 1
    You more or less need to rethink how you are calling and using the data. Javascript is at it's core an event driven language, so you'll have to start thinking about that when you are solving problems. – Andrew McGivery Jul 03 '14 at 14:16