Well, it’s finally over. After five months of rigorous learning, I’ve finished the Flatiron curriculum, and this project is the culmination of my skills to date.
I’ve mentioned my background with p5.js in a few of my blogs. It’s a javascript library for creative coding, and I spent a year working with it when I was in art school. I really wanted to incorporate p5 into a project, and I finally got the chance.
I often start my projects out with a technical challenge in mind, and integrating p5 with React was my technical goal this time around. After a little research I found a react-p5 package that helps you do just that.
NPM React-p5 && Persisting Images
Before I could build my app, I needed to verify that I could accomplish some things first. First and foremost: Can I get a p5.js sketch up and running? I started with a simple “hello world”-style sketch that had some movement to verify that it would work.
Click here for the above code.
It took a quick minute to figure out, but using this package was pretty sweet. If you’re familiar with p5, some things to note when using this package with React:
All functions and methods that are proprietary to the p5 library come into your setup and draw functions as parameters as an object. So, when you call any p5-specific method you have to prefix it with p5. It’s also important to note that if you write any functions that need to access the p5 library, I found the best way to do that was just to do it inside the setup function.
The p5 code I ended up implementing for my react-p5 experiment ended up being very much based upon the Coding Train’s Kaleidescope Snowflake Challenge by the famous Dan Shiffman (who was a former professor of mine).
Now that I had a react-p5 proof of concept, I needed to know whether or could successfully send a p5 sketch to my backend as an image, persist it, and then be able to render it to my front end. This was tricky.
I know a lot about blobs now
Writing code to let a user save an asset to their local hard drive is a relatively easy thing to do. But what if I just want to send it straight to my backend? And wouldn’t that be rude to save that image to the user’s computer just so I can have it in my server?
Enter toBlob().
Obviously the information I needed to persist to my database existed. I’m seeing it on my screen. It exists as binary data. The toBlob() method does exactly that. It takes an html element and converts it to binary (which is essentially what a blob is). I used a query selector to access the p5.js canvas, converted it to a blob, and then put that blob into FormData. Additionally, you can’t send binary as json (as far as I know), so FormData came to the rescue as a means of shipping the binary to my backend. If you haven’t worked with FormData before, it behaves very strangely, and it’s not that straight-forward to inspect it. If you try to look at a key you put into your FormData in the developer console it will come back empty.
Any methods that exist on FormData return iterators, so you can’t see anything you call on it unless you actually iterate over it. It’s really weird. Here’s a stackoverflow article about how to inspect it. It’s very strange.
Here’s how I sent my p5js visual data to my backend. The first block is from my CreateSketches component, while the second is from my sketch actions (redux).
What Am I Supposed to Do with a Blob in Rails?
This part got very tricky. Actually, that’s not totally true. I spent probably half a day trying to figure out what I was doing wrong until I realized that ActiveStorage doesn’t seem to work probably past version 5.2. The docs also don’t go past that, so I guess it makes sense.
Once I actually got ActiveStorage setup (which is pretty sweet once it’s actually working, it went pretty well. ActiveStorage, by the way, is just a Rails framework that helps you attach files to your ActiveRecord models. What’s beautiful about it is that you don’t actually need a file… just a blob. And from there you can create the file solely in your database. This is what my model ended up looking like when it was all said and done. I also had to write custom readers in order for the ActiveStorage assets to be able to bundled into json (with the assets as usable img src urls).
Redux
One of the requirements for this project were that we incorporate redux into our React app. That took me while to get my head around. Well, the flow of it at any rate. If you’re new to redux or similar state management frameworks, it can be a lot. But, don’t be discouraged. I feel like redux (as well as a lot of coding challenges) are best understood through repetition. You don’t have to understand it right away. Just implement it and work with it a bunch and it will start to make sense.
Personal Note
It’s worth mentioning, because it might not be so obvious in the future, that these projects and this bootcamp were done during the COVID-19 pandemic of 2020. There’s been a lot of uncertainty for everyone, a lot of death, and a lot of fear. And I just want to take this opportunity to point out that I couldn’t have made it this far in this program without the support of my wife, Marina, my family and the stalwart individuals that I’ve come to call friends that are my fellow cohort members.