global Array.length has value inside function but is 0 outside function but still has same objects

I have created a function to loop through a weeks worth of employee shifts to pull out only today's shifts. The function as expected. When I output the todayAr in console at the end of the function, I get:

Array[4]    // 4 here...all is good
 >0:Object
 >1:Object
 >2:Object
 >3:Object
 length:4

-- the array of objects with an accurate array length.

But when I reference that same variable with console in a 'document.ready(function()' block, I get:

Array[0]   // notice the 0...can't loop or reference the objects
 >0:Object
 >1:Object
 >2:Object
 >3:Object
 length:4

I can't loop through the array because the length is 0 and any reference using [0], [1] etc returns undefined. This has been driving me crazy for about 8 hours...I have tried every variation for building the object and always seem to get the same result which means I am probably missing something stupid and obvious but just can't see it.

Here is the call:

$(document).ready(function() {          
    var todayAr = [];
    getTodayShifts(todayAr);
    console.log(todayAr);   // length here is 0 but the array elements are there        
});

Here is the function:

function getTodayShifts(a) {
    var d = new Date(); 
    var thisDay = getSpan( d, 'd');
    var i = 0;  
    fetchJSONFile('data/dataSch.cfm', function(data){                                               
        var StartDate;
        $.each(data, function(key, val) {                           
            StartDate = getSpan( val.StartDate, 'd');                                                           
            if (thisDay == StartDate)  { 
                a[i] = addSchedule(val.SID, val.empID, val.StartDate, val.EndDate, val.deptId, val.idn, val.secID);                         
                i++;                                    
            }                                           
        });                 
        console.log(a); // everything is fine here
    });
    return;
} 

Here is the addSchedule function:

function addSchedule(SID, empID, StartDate, EndDate, deptId, idn, secID ) {
    var item = {"SID":  SID,
        "empID":  empID,
        "StartDate":  StartDate,
        "EndDate":  EndDate,
        "deptId":  deptId,
        "idn":  idn,
        "secID":  secID};   
    return item; 
}

Answers 1

  • The fetchJSONFile call is an asynchronous call meaning it initiates the process but returns the results at some later time. This means that a is still empty when you return from the function. That is what you are seeing - length is 0 because at that time it is still an empty array.

    Some time later, the results are available, so fetchJSONFile calls the provided function (the second parameter in your function call), providing it the data. At that point you have the data but not prior.

    To get the data in your document.ready logic you will need to do something like this:

    $(document).ready(function() {
      getTodayShifts(function(data) {
        console.log(data);
      });
    });
    
    function getTodayShifts(cb) {
      var a = [];
      var d = new Date();
      var thisDay = getSpan( d, 'd');
      var i = 0;
      fetchJSONFile('data/dataSch.cfm', function(data){
        var StartDate;
        $.each(data, function(key, val) {
          StartDate = getSpan( val.StartDate, 'd');
          if (thisDay == StartDate)  {
            a[i] = addSchedule(val.SID, val.empID, val.StartDate, val.EndDate, val.deptId, val.idn, val.secID);
            i++;
          }
        });
        console.log(a); // everything is fine here
        cb(a);
      });
    } 
    

    This uses a "callback" function, a common approach to handling situations where getting data is not immediate.


Related Articles