From 890b34bcc1a6b4073d1e512b1386634f7bc5ea52 Mon Sep 17 00:00:00 2001 From: "Adam T. Carpenter" Date: Wed, 21 Apr 2021 22:57:39 -0400 Subject: unified posts dir, until I can figure out makefile sub-subdirs. makefile auto-generates index --- ...021-01-28-undefined-javasript-is-undefined.html | 163 +++++++++++++++++++++ 1 file changed, 163 insertions(+) create mode 100644 posts/2021-01-28-undefined-javasript-is-undefined.html (limited to 'posts/2021-01-28-undefined-javasript-is-undefined.html') diff --git a/posts/2021-01-28-undefined-javasript-is-undefined.html b/posts/2021-01-28-undefined-javasript-is-undefined.html new file mode 100644 index 0000000..e12203b --- /dev/null +++ b/posts/2021-01-28-undefined-javasript-is-undefined.html @@ -0,0 +1,163 @@ + + + + + + + + + + + + + 53hornet ➙ Undefined? JavaSript Is Undefined. + + + + + +
+

Undefined? JavaSript Is Undefined.

+ +

+ So I've been working on a web app for my mom. Nothing too fancy, but + it's a store front for her glass art. It's an easy way for her to keep + track of inventory, update photos of her products, and for people to + shop and search and sort and browse through it. This backend is an HTTP + service written in Rust. The frontend is a Vue.js app. I've used Vue and + JavaScript many times before but I recently ran into an incredibly + strange bug. One that I would have hoped JavaScript would have some + guard against. But JavaScript is an undefined language. +

+ +

+ I have a small component that uses a file input to collect an image from + the user. Then I append that file to a FormData and set that FormData as + a Fetch API request body. So I've got fetch API sending + multipart/form-data across the network to my backend. Awesome! The + backend is supposed to take each field of the request, turn the chunks + into a single stream of binary data, and write them out to an image. + Everything on the front seems like it's working great, it fires off the + request and throws no errors. But then the backend only sees a few bytes + of this multi-megabyte image. Not awesome! short chunks on the back-end. + The array of data in the API is less than ten bytes long, when this is a + many-kilobyte file I'm trying to upload. +

+ +

+ At this point I'm relentlessly debugging, trying to find out what's + wrong with the API. Why is it truncating the request down to a few + bytes, where's the rest of the data? It took me forever to actually + inspect what those few bytes are and, lo and behold they're ASCII for + undefined The request happily stringified an + undefined object, instead of maybe throwing a null + reference or undefined error during request creation because that's just + what JavaScript does. The linter didn't even catch it. +

+ +

+ You can see what the debugging logs looked like on the backend below. + Note that the &data is the field that spells out + "undefined". Also note that the file picker/FormData was constructed + alright because the key for the image name is correct. +

+ +
+		
+[src/handlers.rs:114] &field =
+Field: application/octet-stream
+  boundary: ---------------------------175314640631070190963311652907
+  headers:
+    "content-disposition": "form-data; name=\"clu.jpg\""
+
+[src/handlers.rs:119] &chunk = Ok(
+    b"undefined",
+)
+[src/handlers.rs:123] &data = [
+    117,
+    110,
+    100,
+    101,
+    102,
+    105,
+    110,
+    101,
+    100,
+]
+ImageWrite("The image format could not be determined")
+		
+	
+ +

+ The working JS is here (it was late at night and I was so + donion rings I just fixed it and pushed it without saving the errors for + posterity): +

+ +
+	  
+let file = event.target.files[0];
+if (!file) {
+	return;
+}
+
+const fd = new FormData();
+fd.append(file.name, file);
+
+const response = await fetch("http://localhost:8000/photos", {
+	method: "POST",
+	body: fd
+});
+
+console.log(response);
+	  
+	  
+

+ I've gotten frustrated by JS before but not like this. I don't know if + TypeScript would have solved this issue but writing in a language that + gets transpiled back into the language I'm trying to avoid doesn't seem + like the way forward. I'm looking forward to Web Assembly as a way of + using more type-safe languages in the browser. +

+
+ + -- cgit v1.2.3