I am trying to make a simple csv to JSON converter (just to practice) but I haven't found any way to grab the data from the FileReader()
function with a return. I don't know if this is even possible.
So what the code below does: it just grabs a csv file and after pressing the button to it tries to run a function that converts it to an array (so far). What prints the array is the console.log which works ok but what if I wanted to return this array so I can pass it to another function? Whenever I use return csvArray;
and then instead of running the function trying to console.log(fileToArray(fileinput));
I get undefined. I haven't found anything online regarding this that uses vanilla JS.
const fileinput = document.querySelector("#csvfile").files[0];
const convertBtnFile = document.querySelector("#convertBtn");
convertBtnFile.addEventListener("click", (e) => {
e.preventDefault();
fileToArray(fileinput);
});
const fileToArray = (csvFile) => {
const myFile = new FileReader();
myFile.onload = (event) => {
const wholeText = event.target.result;
const splitLines = wholeText.split(/\r\n|\n/);
csvArray = splitLines.map(i => i.split(","));
console.log(csvArray);
}
myFile.readAsText(csvFile);
}
<input type="file" id="csvfile" /><br/> <button type="button" id="convertBtn">Convert</button>
One thing your code does wrong is
const fileinput = document.querySelector("#csvfile").files[0];
straight away - you want to wait until you're in the click handler before you try to read the file
The simplest answer for you is to use a callback in fileToArray
function
const convertBtnFile = document.querySelector("#convertBtn");
convertBtnFile.addEventListener("click", (e) => {
e.preventDefault();
const fileinput = document.querySelector("#csvfile").files[0];
fileToArray(fileinput, data => {
// do things with results here *********
});
});
const fileToArray = (csvFile, cb) => { // ********
const myFile = new FileReader();
myFile.onload = (event) => {
const wholeText = event.target.result;
const splitLines = wholeText.split(/\r\n|\n/);
csvArray = splitLines.map(i => i.split(","));
cb(csvArray); // **** call the supplied function with the results
}
myFile.readAsText(csvFile);
}
If you're comfortable with async/await, you can do this - the benefit is, it "looks" synchronous
const convertBtnFile = document.querySelector("#convertBtn");
// note: vvvvv async
convertBtnFile.addEventListener("click", async (e) => {
e.preventDefault();
const fileinput = document.querySelector("#csvfile").files[0];
const data = await fileToArray(fileinput);
// do things here
});
const fileToArray = csvFile => {
return new Promise((resolve, reject) => {
const myFile = new FileReader();
myFile.onload = event => {
const wholeText = event.target.result;
const splitLines = wholeText.split(/\r\n|\n/);
csvArray = splitLines.map(i => i.split(","));
resolve(csvArray);
}
myFile.onerror = reject;
myFile.readAsText(csvFile);
});
};