2

I'm trying to parse a local csv file in an Angular/Sinatra project - preferably using D3, but have also tried the HTML5 file API, Papa.parse, and an ajax call. However, I keep getting a 404 error with ajax, d3, and HTML5, and an empty dataset with Papa. The file is saved in the same level as the application.js folder.

Can anyone tell me why?

Here's my code, including many of the various things I've tried:

application.js:

 angular.module('Project', ['ngRoute', 'ngResource'])

 .config(function($routeProvider) {
     $routeProvider

     // route for the calculator page
     .when('/', {
         templateUrl: 'partials/display.html',
         controller: 'displayController'
     })
    // tried giving the csv a route to link to but this didn't work
    .when('/data', {
         templateUrl: 'partials/dataset.csv',
         controller: 'dataController'
     })
 })

 .controller('displayController', function($scope, $http) {
  var dataset

  // this gives a 404 error
  d3.csv('challengedataset.csv', function(data) {
    dataset = data;
  })

  // these give an empty datset
  var results = Papa.parse("challenge-dataset.csv", function(data) {
   dataset = data
 });

  Papa.parse('challenge-dataset.csv', {
    worker: true,
    step: function(row) {
      dataset = row
    },
    complete: function() {
     console.log("All done!");
    }
 });

// these gave me a 404 error
var reader = new FileReader();
reader.onload = function(e) {
  var text = reader.result;
}
var dataset = reader.readAsText('challenge-dataset.csv');
 })

$.ajax({
    type : 'GET',
    dataType : 'json',
    url: 'challenge-dataset.csv',
    success : function(data) {
      dataset = data
    } 
});

console.log(dataset)
Car
  • 337
  • 2
  • 4
  • 14
  • Sorry to ask an obvious question but are you serving the data up from a web server? – user1614080 Sep 29 '14 at 06:36
  • Try a leading `/` in the ajax url. – sideroxylon Sep 29 '14 at 06:51
  • I'm a relative beginner so my apologies if this isn't very clear - I've got it saved down in the same directory as the rest of the app, and have required it in the index.html file. Since the index.html file is being served, and it's included in that, I assume it's being served too? – Car Sep 29 '14 at 06:55
  • 1
    I have a number of applications downloading csv files with ajax code very similar to yours (other than the datatype) - so my guess is a path error. Have you checked the network in the console to see what's happening? You should be able to see the csv data in the response. If it got there. – sideroxylon Sep 29 '14 at 07:13
  • Previously it was giving me a 404 error, but now I've updated to (presumably) the correct path, and console.log(dataset) is returning 'undefined'. Do you know how I might debug that one? – Car Sep 29 '14 at 07:19

2 Answers2

3

This may have to do with d3 treating .csv calls asynchronously. Have you seen this response by Mike Bostock? Basically, code within the d3.csv call is run last (to prevent freezing). If you need to capture that data into the DOM, you'll need to do it within the d3.csv call itself. The API for further info.

        //1. code stuff

        d3.csv("your file.csv", function(d) {
            //2. bunch of other code
        })

        //3. a third set of code stuff

So the above would run 1-3-2.

Community
  • 1
  • 1
goblin-esque
  • 465
  • 5
  • 15
  • Thanks - I did read the response, and found it very helpful. Unfortunately I think my problem may be even more basic than that, as I seem to be having trouble simply accessing the file in the first place. Since I define the var dataset outside of the d3 function, that should handle the asynchronous call, right? – Car Sep 29 '14 at 07:00
  • Looking closer at this, using the d3.csv method (once I fixed the path), it looks like I am, in fact, returning the data from the array. So it's definitely an asynchronous issue. Thank you for suggesting I take another look at this! – Car Sep 29 '14 at 07:37
1

If you give Papa Parse a URL, you need to set download: true in the configuration, otherwise it thinks that the string you give it is literal CSV values to parse. Also, you're not doing anything useful with the results. Try something like this:

Papa.parse('challenge-dataset.csv', {
    worker: true,
    download: true,
    step: function(row) {
      console.log(row);
      dataset = row
    },
    complete: function() {
     console.log("All done!");
    }
 });

Here we're just printing each row to the console, so beware if you're using this for a large file! But at least it's something you can try for debugging. You might try something like letting preview: 10 to limit how many rows are parsed as you debug.

Matt
  • 22,721
  • 17
  • 71
  • 112