Skip to content

[p5.js 2.0+ Bug Report]: loadTable() drops the last row of a one-column CSV without a trailing newline #9222

Description

@Abhist17

Most appropriate sub-area of p5.js?

  • Accessibility
  • Color
  • Core/Environment/Rendering
  • Data
  • DOM
  • Events
  • Image
  • IO
  • Math
  • Typography
  • Utilities
  • WebGL
  • WebGPU
  • p5.strands
  • Build process
  • Unit testing
  • Internationalization
  • Friendly errors
  • Other (specify if possible)

p5.js version

2.3.4 (also on main)

Web browser and version

Chrome 153

Operating system

Linux

Steps to reproduce this

loadTable() drops the last row of a one-column CSV that doesn't end with a newline. If the file is a single value, it throws instead.

With names.csv containing alice\nbob\ncarol (no newline at the end):

async function setup() {
  noCanvas();
  const t = await loadTable('names.csv');
  print(t.getRowCount()); // 2, expected 3
  print(t.getArray());    // [["alice"], ["bob"]]
}
  • alice\nbob\ncarol\n (with a trailing newline) gives 3 rows, as expected.
  • A file containing just 42 throws Cannot read properties of undefined (reading 'length'). FES then reports "there was a problem loading your table file. Try checking if the file path is correct", which sends people looking at the wrong thing.
  • Multi-column files aren't affected: x,y\n1,2 parses fine without a trailing newline.

The cause is in src/io/csv.js, at the end of parse():

// flush the last value
if (ctx.entry.length !== 0) {
  valueEnd(ctx);
  entryEnd(ctx);
}

ctx.entry only gets a value when a separator or newline ends it. In a one-column row, the last value is still sitting in ctx.value with ctx.entry empty, so the flush is skipped. parse('a\nb') returns [["a"]], parse('only') and parse('"only"') return [], and parse('a\n\nb') loses the b. For the single-value file, loadTable then does data[0].length on an empty array.

I think the fix is to flush whenever the parser is partway through a value, i.e. if (state !== 0 || ctx.entry.length !== 0). State 2 covers an unquoted value and 4 covers a closed quote. A trailing newline leaves state 0 with an empty entry, so it still doesn't add a phantom row. A separate guard in loadTable for an empty file (data[0] undefined) would make that case return an empty table instead of throwing. I'm happy to open a PR with both and unit tests for parse if this sounds right.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions