Klon
Klon

Reputation: 445

CSV to array - jquery and ajax problem

I'm trying to implement a function which would load a server-stored CSV file, and parse it into an array. I have some issues with it and would be grateful for help.

Here's how the function looks like at the moment:

  function getSeries(filename){
   //create an array where objects will be stored.
   var seriesInFile=[];
   $.get('/public/csv/'+filename+'.csv',
        function(data) {
            // Split the lines
            var lines = data.split('\n');
            $.each(lines, function(lineNo, line) {
                var items = line.split(',');
                //elements from each line are taken and stored
                series = {
                             //some other attributes here, I took them off for this example
                             data: []
                         }
                $.each(items, function(itemNo, item) {
                        series.data.push(parseFloat(item));
                });
               seriesInFile.push(series);
            });
        console.log(seriesInFile); //it works here!
        });
     return seriesInFile;
    }; 
   console.log(getSeries('hr'));
   console.log(getSeries('hr'));

So, the problem is that even though I successfully get information from the CSV file and store it within 'seriesInFile' within the $.each function, as soon as I get out of it it doesn't work anymore - whole function returns an empty array. I guess it might have something to do with the get() function being deployed a bit later than the original getSeries one. Is there a simple solution for it?

Thanks,

Upvotes: 2

Views: 4686

Answers (2)

Nicola Peluchetti
Nicola Peluchetti

Reputation: 76870

I think you must return seriesInFile from the callback function of $.GET

  function getSeries(filename){
   //create an array where objects will be stored.
   var seriesInFile=[];
   $.get('/public/csv/'+filename+'.csv',
        function(data) {
            // Split the lines
            var lines = data.split('\n');
            $.each(lines, function(lineNo, line) {
                var items = line.split(',');
                //elements from each line are taken and stored
                series = {
                             //some other attributes here, I took them off for this example
                             data: []
                         }
                $.each(items, function(itemNo, item) {
                        series.data.push(parseFloat(item));
                });
               seriesInFile.push(series);
            });
        console.log(seriesInFile); //it works here!
        // do what you need to do with seriesInfile here 
        //like calling a function to display it

        });
      //here seriesInFile is an empty array; 
    }; 

Since $.GET makes an asynchronous call to the server, all the other code gets executed: in your example you return seriesInFile as an empty array because your function doesn't wait for the AJAX call to be completed and just returns seriesInFile as you declared it. If you want to return it you must do so in the callback function of $.GET that is executed on success of the AJAX call.

EDIT - As suggested in the comment returning from the callback probably doesn't work (never tried it). Usually you should do whatever you need to do directly from the callback function (that's what i usually do ). If you need help with something in particular i can help

Upvotes: 1

Codo
Codo

Reputation: 78795

As Nicola Peluchetti correctly pointed out, the GET request is asynchronous. That means it starts when you called $.get but if finishes later. The function getSeries returns immediately. At this point in time, the array is still empty because the GET request hasn't finished.

Whatever you want to do with the parsed CSV data, you have to initiate it from callback of the GET request and not from the function that called getSeries (which would better be called startSeriesRetrieval).

So it could look like this (displaySeries is called to further work with the retrieved data):

function startSeriesRetrieval(filename) {
  $.get('/public/csv/'+filename+'.csv',
    function(data) {
      // Split the lines
      var lines = data.split('\n');
      var seriesInFile=[];
      $.each(lines, function(lineNo, line) {
        var items = line.split(',');
        //elements from each line are taken and stored
        series = {
          //some other attributes here, I took them off for this example
          data: []
        }
        $.each(items, function(itemNo, item) {
          series.data.push(parseFloat(item));
        });
        seriesInFile.push(series);
      });
      displaySeries(seriesInFile);
    }
  );
}; 

Upvotes: 1

Related Questions