0

I am using PapaParse to parse multiple CSV files. The file selector has them in the order of A B C D E, but they aren't always parsed in that order. I understand that it is because PapaParse will finish up with one file before another, but it is crucial that I parse them in the order that they appear from the file selector i.e. alphabetical.

var Files = $('input[id="upload"]')[0].files;
var allProcessed = [], allDates = [];
for (i in Files)
{
  const date = new Date(Files[i].lastModified);
  allDates.push((date.getMonth() + 1) + '/' + date.getDate() + '/' + date.getFullYear());

  Papa.parse(Files[i],
  {
    skipEmptyLines: true,
    complete: function(results)
    {
      allProcessed.push(results);
      if (allProcessed.length == Files.length)
      {
        console.log('all done');
      }
    }
  }
}
user9675088
  • 29
  • 1
  • 5
  • 1
    looks like `Papa` is async so they happen to go out of order... – Daniel A. White Sep 07 '18 at 17:46
  • [Don't use `for…in` enumerations on arrays!](https://stackoverflow.com/q/500504/1048572) – Bergi Sep 07 '18 at 17:53
  • "*it is crucial that I parse them in the order that they appear from the file selector i.e. alphabetical*" - why exactly is that? If you just care that they appear in the same order in the result (after having been processed in paralled), just use `allProcessed[i] = results` instead of `push` – Bergi Sep 07 '18 at 17:55

2 Answers2

1

From the Papa Parse documentation:

Papa.parse(file, config): doesn't return anything. Results are provided asynchronously to a callback function.

So the parse order is not guaranteed. If you really need them to be parsed in order, you could start the next parse when one parse finishes.

Here is an example of how you could chain the calls to Papa.parse(), assuming you have an array of files:

const files = [ /*an array of files*/ ];
let currentIndex = 0;

function getNextFile() {
  return files.length == currentIndex? null : files[currentIndex++];
};

const config = {
  skipEmptyLines: true,
  complete: function(results) {
    allProcessed.push(results);
    parseNextFile();
  }
};

function parseNextFile() {
    const file = getNextFile();
    if (!file) {
      console.log('all done');
    } else {
      Papa.parse(file, config);
    }
};

parseNextFile();
HugoTeixeira
  • 4,674
  • 3
  • 22
  • 32
0

It looks like you need to handle asynchronous actions in a for loop. That does tend to get a little tricky. The first answer in this post looks like it could answer your question.

Try doing a recursive function that calls itself as the callback finishes. Something like the following but more towards what that other guy in the post had.

    function recursiveRead() {
        readFile(file, () => {
            recursiveRead();
        })
    }
Andrew Gremlich
  • 353
  • 4
  • 7