LocalFile
***Update Oct. 2021:*** *Observable now supports [**file inputs**](/@observablehq/input-file)! This notebook will remain for history, but please upgrade to [Observable Inputs](/@observablehq/inputs).*
A hack to treat a local file as an Observable FileAttachment, so that you get all the same conveniences (e.g., loading CSV or SQLite). Pass the value option to set the initial value to a file attachment.
const fileView = localFileInput({accept: ".db"})
const file = Generators.input(fileView)
fileView
const db = display(await file.sqlite())
display(await db.describe())
function localFileInput({
accept, // e.g., ".txt,.md"
value // set the initial value (typically to a FileAttachment)
} = {}) {
return Object.assign(htl.html`<form><input type=file ${{accept}} oninput=${(event) => {
const {currentTarget: input} = event;
const {form, files: [file]} = input;
form.value = new LocalFile(file);
}}>`, {value});
}
class LocalFile extends AbstractFile {
constructor(file) {
super(file.name);
Object.defineProperty(this, "_", {value: file});
Object.defineProperty(this, "_url", {writable: true});
}
async url() {
return this._url || (this._url = URL.createObjectURL(this._));
}
async blob() {
return this._;
}
async stream() {
return this._.stream();
}
};
display(LocalFile)
const AbstractFile = FileAttachment("/data/empty@1").constructor.__proto__
display(AbstractFile)