0

I want to create a simple function that reads some json, does some simple processing, and returns an array as a result.

I currently have the code below. However, the function always returns [].

If I move temps to the global scope, it first returns [], then the second time it's called the data is added, and the third time it's called it's double the length etc.

function getTempData() {
    var temps = [];
    $.getJSON('temp.json', function(data) {
    data = data.observations.data;

    for(var i = 0; i < data.length; i++) {
        year    = parseInt(data[i].aifstime_utc.substr(0, 4));
        month   = parseInt(data[i].aifstime_utc.substr(4, 2));
        day     = parseInt(data[i].aifstime_utc.substr(6, 2));
        hour    = parseInt(data[i].aifstime_utc.substr(8, 2));
        min     = parseInt(data[i].aifstime_utc.substr(10, 4));
        time = Date.UTC(year, month, day, hour, min);

        temps.push([time, data[i].air_temp]);
    }
});
return temps;
}

looking at some other questions, it seems this may have something to do with asynchronism? Is there a way to get it to load synchronously, I would like to graph the data in a highchart.

mercifulhop
  • 271
  • 3
  • 11
  • what happens if you console.log(data)? does it actually contain any data? – kennypu Mar 11 '13 at 06:25
  • You can make the AJAX call synchronous, but it's a really bad idea. Look at already existing answers on how AJAX callbacks work, it's been explained millions of times. (And stop creating global variables.) – DCoder Mar 11 '13 at 06:28

1 Answers1

1

dakait was almost there, because of the asynchronyous nature of the ajax call your function returns before the function processing the data has been called. Consider the following example:

function test(){
  var done=false;
  setTimeout(function(){
    done=true;
  },500);
  return done;
};
alert(test());//will say false

In your code you need 3 functions: 1) call the getTempData 2) fetch the data from the server 3) process the data

function getTempData() {
    var temps = [];
// 2) fetch the data
    $.getJSON('temp.json', 
    function(data) {
// 3) process the data
    data = data.observations.data;

    for(var i = 0; i < data.length; i++) {
        year    = parseInt(data[i].aifstime_utc.substr(0, 4));
        month   = parseInt(data[i].aifstime_utc.substr(4, 2));
        day     = parseInt(data[i].aifstime_utc.substr(6, 2));
        hour    = parseInt(data[i].aifstime_utc.substr(8, 2));
        min     = parseInt(data[i].aifstime_utc.substr(10, 4));
        time = Date.UTC(year, month, day, hour, min);

        temps.push([time, data[i].air_temp]);
    }
    processTempData(temps);
});
//return temps;//this line executed immediately after $.getJSON is called
// but before function 2) has been called
}

1)
function callgetTempData(){
//...
  getTempData();
  // no use processing anything here since the ajax call is not finished yet
  // asynchronous means that js will not wait until it's done.
  // I would not advice using synchronous
}
2) // further process data
function processTempData(theData){
// do something with the data here
}

In an application with lots of ajax calls that are part of a process you might consider using a mediator pattern:

Good pattern to use for multiple xmlhttprequests used by different processes

Community
  • 1
  • 1
HMR
  • 37,593
  • 24
  • 91
  • 160