-3

I'm having this issue with importing data from a JSON file. I use the .getJSON function to get the data which means to work according to the console log, but once I move out of the getJSON sub function the array in data2 disappears. I've narrowed it down to this section here:

function prepData() {
    data2 = [];

    $.getJSON('http://localhost/data').done(function(json) {
        data2 =json;
        console.log(data2);
    });

    console.log(data2);
    SelectedData = data2;
    return SelectedData;
};

What might the issue be here?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Exostrike
  • 169
  • 10
  • Async code (like your call to getJSON) will not cause your code to halt execution until it completes. This is why it is async. – Mike Cheel Mar 29 '17 at 18:19

3 Answers3

1

Your function:

function(json) {
    data2 = json;
}

is executed after

console.log(data2);
SelectedData = data2;

data2 is not defined yet at that point.


(1) function prepData(){
(2)    data2 = []; 

(3)    $.getJSON('http://localhost/data').done(function(json) {
(4)        data2 =json;
(5)        console.log(data2);
       });

(6)    console.log(data2);
(7)    SelectedData= data2;
(8)    return SelectedData;
   };

Execution order:

1 -> 2 -> 3 -> 6 -> 7 -> 8 -> 4 -> 5

Common practice - Return promise instead of data:

function prepData(){
    return $.getJSON('http://localhost/data');
}

// more code here

prepData().done(function(json){
    console.log(json);
});

Take a look at these more detailed demos.
jQuery on ES5: https://jsfiddle.net/DerekL/xtmy6po0/

function timeout(n){
    // create promise
    var defer = $.Deferred();

    // resolve after n milliseconds
    setTimeout(function(){
        defer.resolve(n);
    }, n);

    // return new promise that apply custom text
    return defer.then(function(v){
        return "Resolved after " + (v/1000) + " seconds";
    });
}

timeout(3000).then(function(message){
    // will be executed after 3 seconds
    alert(message);
});

Equivalent ES7: https://jsfiddle.net/DerekL/8kLknbne/

async function timeout(n){
    // create timer
    let timer = () => new Promise(resolve => setTimeout(() => resolve(n), n));
    // return message
    return "Resolved after " + (await timer()/1000) + " seconds";
}

// call
timeout(3000).then(alert);
Derek 朕會功夫
  • 92,235
  • 44
  • 185
  • 247
  • Well thats stupid. Is there any way to change get Json to run in the order written down? – Exostrike Mar 29 '17 at 18:39
  • @Exostrike That's just how promises are designed to work. Remember you only have one single thread and you can't block a thread since it would also block all UI updates. Instead of returning the data, return the promise (or a deffered object in jQuery) instead. – Derek 朕會功夫 Mar 29 '17 at 18:54
  • @Exostrike Take a look at this demo if you need more help on handling asynchronous calls: https://jsfiddle.net/DerekL/xtmy6po0/ – Derek 朕會功夫 Mar 29 '17 at 19:07
  • @Exostrike Here's a piece of equivalent code in the newest ES7 instead of using jQuery: https://jsfiddle.net/DerekL/8kLknbne/ – Derek 朕會功夫 Mar 29 '17 at 19:26
0

The .done is an event so it will happen few milliseconds or seconds later than the other script, it only occurs when the request to http://localhost/data is completed

this will run first:

$.getJSON('http://localhost/data');
console.log(data2);
SelectedData= data2;
return SelectedData;

few seconds later .done event will be fired then this will run

data2 =json;
console.log(data2);

my suggestion is in the .done function call another function that process the answer, instead of waiting for return value which will return as undefined in your code

Nawwar Elnarsh
  • 1,049
  • 16
  • 28
-2

$.getJSON is asynchronous so it will executed parallel to your next console statement.

Tushar Kotlapure
  • 338
  • 6
  • 14
  • Nope. JavaScript is single threaded, that means (4) and (5) (refer to my answer) must execute after the function returned. – Derek 朕會功夫 Mar 29 '17 at 18:20
  • It won't be executed in parallel. It will be executed at some point after the current code execution finished. (The top of the execution stack is reached on no further code to execute exists). – t.niese Mar 29 '17 at 18:21
  • @t.niese thanks for clarity. That's what i mean to say. – Tushar Kotlapure Mar 29 '17 at 18:23