Skip to content

Commit

Permalink
file-byte-reader
Browse files Browse the repository at this point in the history
  • Loading branch information
knzai committed Aug 10, 2024
1 parent bb54116 commit 630b894
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 0 deletions.
40 changes: 40 additions & 0 deletions _posts/2024-08-10-file-byte-reader.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
---
layout: post
title: "Minimal WebComponent to parse file selectors into bytearrays"
image: /assets/img/projects/file-byte-reader.png
description: >
Extending the HTMLInputElement and using custom events for easy hooks
toot_id: 112919231724048267
---

I'm in the process of moving the (non-wasm parts) of my web front-end for [cega](/projects/cega) over to vanilla Jasvacript WebComponents. I've liked how much it cleans up and encapsulates the logic without even needing a framework. The hooks for parsing the file into a byte array on the client-side (for passing to the wasm) were an obvious extraction point, so I pulled it out to a gist micro-project: [file-byte-reader](/projects/file-byte-reader).

This hides a [lower-level abstraction with its own async, FileReader](https://developer.mozilla.org/en-US/docs/Web/API/FileReader). It also makes a nice real world example of extending an input tag and using custom events to give easy hooks for your WebComponents. I liked the [pattern Chris Ferdinandi was using for having a (partially) curried emit function to make dispatching your events more succinct](https://gomakethings.com/custom-events-in-web-components/), so I've added it to my practices for WebComponents going forward.

```javascript
//attach a listener (to an `is` applied file selector) that will get the parsed byte array:
//<input is="file-byte-reader" id="file-input" type="file"
//$('#file-input').addEventListener("file-byte-reader:loaded", e => YOURHANDLER(e.detail));
class FileByteReader extends HTMLInputElement {
connectedCallback() {
this.addEventListener('change', this.onChange);
}

emit (type, detail = {}) {
let event = new CustomEvent(`file-byte-reader:${type}`, {
bubbles: false,
cancelable: false,
detail: detail
});
return this.dispatchEvent(event);
}

onChange() {
if (this.files.length == 0) { return }
const fileReader = new FileReader();
fileReader.addEventListener('loadend', e => this.emit('loaded', new Int8Array(fileReader.result)));
fileReader.readAsArrayBuffer(this.files[0]);
}
}
customElements.define("file-byte-reader", FileByteReader, { extends: 'input'});
```
16 changes: 16 additions & 0 deletions _projects/file-byte-reader.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
title: file-byte-reader.js
caption: WebComponent to parse a file input into a bytearray
description: >
WebComponent for simpler parsing of a file selector input into a bytearray (like to use in wasm file processing)
date: 10 Aug 2024
image:
path: /assets/img/projects/file-byte-reader.png
links:
- title: "perma"
url: https://knz.ai/projects/file-byte-reader
- title: gist
url: https://gist.github.com/knzai/c297fdd13739e1a844e4001142183459
---

- Language/Platform: Javascript
Binary file added assets/img/projects/file-byte-reader.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 630b894

Please sign in to comment.