I want a cleaner UI than what
<input type="file" ...>
gives me.
I can use window.showOpenFilePicker() to get the user gesture security context and get a "fileSystemHandle" from that API but I can’t figure out how to read that file using the FileReader object. (or any other way)
Here is my failing code:
/**
* Used to import via a simple button.
* The caller must call window.showOpenFilePicker() and give the
* fileHandle to this API.
* @param {*} fileHandle
* @param {*} fnImportToUI
*/
fio.importFromFileButton = async function(fileHandle, fnImportToUI) {
if (Array.isArray(fileHandle)) {
fileHandle = fileHandle[0];
}
var blob;
const reader = new FileReader();
reader.addEventListener('loadend', (event) => {
blob = new Blob([new Uint8Array(event.target.result)], {type: fileHandle.type })
fnImportToUI(fileHandle, event.target.result)
});
reader.readAsArrayBuffer(blob);
}
The problem being that the fileSystemHandle is not a Blob (I get an error if I call
reader.readAsArrayBuffer(fileHandle);
or
reader.readAsText(fileHandle);
or using any of the ReadFile read APIs.)
From what I can tell, I can’t convert the fileSystemHandle to a Blob until I have read the file to get the data – a chicken and egg issue.
2
Answers
You might find this article on Medium quite useful: "Exploring Advanced File Reading in JavaScript: Unleashing the Power of showOpenFilePicker". It delves into the showOpenFilePicker API, which provides an innovative approach to reading files in JavaScript without relying on traditional input fields. The article explains its benefits, demonstrates code snippets, and even discusses real-world use cases. I found it to be a great resource when exploring this topic. Check it out for a detailed exploration of the technique!
There are several mistakes in your snippet, I have fixed based on my assumptions. Code is pretty much self explanatory.