1

Please bare bear with me, I'm very new to Javascript. I am pulling my hair out trying to figure out why this won't work. Keep in mind I come from a Java background. I have a function 'getCsvData' and I'm essentially trying to parse a CSV file and dynamically add object properties to the datasource object and then return it. As you can see, outside the function 'getCsvData', I try to log the results after calling my function, but the result object is empty and there are no object propeties added to it.

I have a very strong feeling it has to due with closure/scope chain resolution that I'm still trying to learn and understand.

The questions are: Why aren't the properties added dynamically to the datasource object? I believe they actually are added in the scope of the anonymous function 'function(data)' passed as the second argument to '$.get', but they are immediately gone once the outer function 'getCsvData' returns. Why, and how can I fix this? Thanks!!

<script src="js/jquery-1.10.2.min.js"></script>
<script src="js/knockout-3.0.0.js"></script>
<script src="js/globalize.min.js"></script>
<script src="js/dx.chartjs.js"></script>
<script src="js/jquery.parse.js"></script>

$(function () {
    function getCsvData(fileName, groupBy, year) {
        var datasource = { }
        $.get(fileName, function(data) {
            var alldata = $.parse(data, { header: true });
            for (var i = 0; i<alldata.results.rows.length;i++) {
                var key = alldata.results.rows[i][groupBy]
                if (key in datasource) {
                    datasource[key] = datasource[key] + 1
                } else {
                    datasource[key] = 0
                }
             }
         });
        return datasource;
    };


    var results = getCsvData("data/data.csv", "Priority", 2012);
    console.log(results)
    for (key in results) {
        console.log(key)
    }
});
acarlon
  • 16,764
  • 7
  • 75
  • 94
HiChews123
  • 1,598
  • 4
  • 20
  • 39
  • Yet another "why doesn't my asynchronous function update immediately?" question. ;-) – RobG Apr 15 '14 at 00:20
  • @RobG, actually I totally forgot that $.get would be async by default, if I had realized that earlier, it would have made this so much easier! Thanks! – HiChews123 Apr 15 '14 at 00:30
  • That's OK, you're one of millions who've said "doh!!" to that. :-) – RobG Apr 15 '14 at 03:09

1 Answers1

2

This is because get is called async, so datasource is the return value after initiating the get rather than after receiving the result (i.e. it is empty because the get completion has not been called yet). You should rather indicate completion with a callback or use jQuery.ajax() with the sync option to wait for the response to the get before returning from getCsvData. See here.

Community
  • 1
  • 1
acarlon
  • 16,764
  • 7
  • 75
  • 94