Skip to content

How to read a csv file from input element with vanilla js?

I’ve been trying to read a csv file provided by the user with html form and then process the data. I wanted to approach this with Fetch. It works great when reading a file located on a server.

const response = await fetch('../csv/datafile.csv');
const data = await response.text();

Problem starts when I want to let the user pick a local file.

<input type="file" name="input_file" id="input_file" accept=".csv">
const formFile = document.querySelector('#input_file');
formFile.addEventListener('change', getData, false);

async function getData() {
    const response = await fetch('formFile.files[0].name');
    const data = await response.text();
}

Of course it doesn’t work as it takes correct file name but thinks it’s on the server. I have tried it many other ways but got fakepath, object element, CORS and other issues.

I have also tried to approach the problem with FileReader, got the data but faced promiseless async problems and couldn’t await for the data to put them outside in a variable.

What’s the best approach? Is it possible to solve the problem with vanilla js without uploading the file to the server? I thought this should be super easy, even for an absolute beginner like me but I wasted so much time and thought to ask you for help. Maybe there’s something else that I’m doing wrong. Thank you for help.

Answer

Here’s how you’d do this, adapted from this question.

const formFile = document.querySelector('#input_file');
formFile.addEventListener('change', getData, false);

function getData() {
  if (!window.File || !window.FileReader || !window.FileList || !window.Blob) {
    console.log('The File APIs are not fully supported in this browser.');
    return;
  }

  if (!formFile.files) {
    console.log("This browser doesn't seem to support the `files` property of file inputs.");
  } else if (!formFile.files[0]) {
    console.log("No file selected.");
  } else {
    let file = formFile.files[0];
    let fr = new FileReader();
    fr.onload = receivedText;
    fr.readAsText(file);

    function receivedText() {
      console.log(fr.result);
      // Do additional processing here
    }
  }
}
<input type="file" name="input_file" id="input_file" accept=".txt">