0

Currently I'm returning a JSON object back to a javascript array. The array contains all the correct data (I used Firebugs console.debug() feature to check this), however when I'm trying to use the data within the array, it says it's undefined.

Here is the function which returns the JSON object:

function populateVals(sess, stepSize) {
    var items = new Array();
    var run;

    // Check if one or multiple files need to be processed
    if(sess.indexOf("|") >= 0) {
        alert("Multiple files");
    } else {    
        $.ajax({
            url:"json/getVals.php",
            data: {email: GLOBAL.email, actDate: sess, stepSize: stepSize},
            type: "POST",
            dataType: "json",

            success: function(json) {
                items.push(json);
            },
            error: function (xhr, status, errorThrown) {
                alert( "Sorry, there was a problem!" );
            }
        });
    }
    return items;
}

And here is code segment of code which attempts to use the array:

var results = new Array();
    results = populateVals(sess, stepSize);
    console.debug(results);

    GLOBAL.results = results.distances; //used by toExcel

    var data = [];
    var data2 = [[0,0],[16.15,0]]; //try to draw alternate x axis showing minute-miles
    var x = 0.0;
    var y;

    for(var i = 0;i < results.distances.length; i++){
        y = results.distances[i];
        data.push([x,y]); //change a plot point y to [x,y]
        //x += 1/10;
        x += stepSize;
    }

The undefined error occurs in the following line of the above segment where results.distance is undefined:

for(var i = 0;i < results.distances.length; i++){

Also, here is a dump of the array from firebug, it helps show what Im actually referencing with regards to distance (where distances itself is an array):

Object { distances=[26], stepSize=1, TotalTimeSeconds=1396951626, more...}

TotalDistanceMeters
    2462.86

TotalTimeSeconds
    1396951626

distances
    [0, 0.40603201156379, 0.81206402312758, 23 more...]

0
    0

1
    0.40603201156379

2
    0.81206402312758

3
    0

4
    0

5
    0

6
    0

7
    0

8
    0

9
    0

10
    0

11
    0

12
    0

13
    0

14
    0

15
    0

16
    0

17
    0

18
    0

19
    0

20
    0

21
    0

22
    0

23
    0

24
    0

25
    0

Many thanks in advance for any help that can be provided

Ash W
  • 55
  • 1
  • 8
  • This helped! Thank you. I should have made my searches a bit broader before posting. But I wouldn't have guessed that this was the issue. – Ash W Apr 19 '14 at 17:18

4 Answers4

2

jQuery AJAX is Async by default. So when you call the function results = populateVals(sess, stepSize); it makes a request to the server and continues with the execution of the next code. So when you say results.distances the server might have not returned the result, resulting in indefined error.

Also, you are overriding the result array with an object from response. Check that too.

Swadeesh
  • 576
  • 1
  • 4
  • 23
  • Ah. makes sense - I have set Async to false. However I'm not sure what you mean when you say my result array is being overridden with an object? – Ash W Apr 19 '14 at 16:46
  • He's not overwriting the result, he's pushing it into an array. I dont think it needs to be an array though, just pass the result JSON to your function. – jamis0n Apr 19 '14 at 22:35
0

Like the other posters suggest, you should use a callback function, as populateVals will return an empty array everytime since the AJAX call is not complete.

Assuming the data has returned from the server correctly (using a callback), results is an array, which means you need to loop through all of the "items" in that array and then look at the distances array in each item.

to reference the first item's distances array:

results[0].distances

Here is the possible alternative using a callback function. It also looks like you dont need to return an array, as everytime the array will only have 1 item:

function processData(json){
    var results = json;
    console.debug(results);

    GLOBAL.results = results.distances; //used by toExcel

    var data = [];
    var data2 = [[0,0],[16.15,0]]; //try to draw alternate x axis showing minute-miles
    var x = 0.0;
    var y;

    // for each distances value in the result
    for(var i = 0;i < results.distances.length; i++){
        y = results.distances[i];
        data.push([x,y]); //change a plot point y to [x,y]
        //x += 1/10;
        x += stepSize;
    }
}

function populateVals(sess, stepSize) {
    // Check if one or multiple files need to be processed
    if(sess.indexOf("|") >= 0) {
        alert("Multiple files");
    } else {    
        $.ajax({
          url:"json/getVals.php",
          data: {email: GLOBAL.email, actDate: sess, stepSize: stepSize},
          type: "POST",
          dataType: "json",
          success: function(data) {
            processData(data);
          },
          error: function (xhr, status, errorThrown) {
            alert( "Sorry, there was a problem!" );
          }
        });
    }
}
jamis0n
  • 3,610
  • 8
  • 34
  • 50
0

The problem is that the $.ajax() method is asynchrounous. In other words, your code will continue executing while the server has not responded yet. Therefore, yourpopulateVals() method will return an empty array.

The only way to solve this would be to add some sort of a callback parameter to your function, that then gets the values passed and does any further processing.

ced-b
  • 3,957
  • 1
  • 27
  • 39
0

The ajax call in populateVals(sess, stepSize) is asynchronous which means the function will return before the ajax completes. Add async: false to force synchronous behaviour:

    $.ajax({
        url:"json/getVals.php",
        data: {email: GLOBAL.email, actDate: sess, stepSize: stepSize},
        type: "POST",
        dataType: "json",
        async: false, //async

        success: function(json) {
            items.push(json);
        },
        error: function (xhr, status, errorThrown) {
            alert( "Sorry, there was a problem!" );
        }
    });
Wilmer
  • 2,511
  • 1
  • 14
  • 8