My First Hackathon: Why Does Everything Have to Keep Breaking?!
https://github.com/GuardianBob/PaintApp

My First Hackathon: Why Does Everything Have to Keep Breaking?!

Disclaimer: this post is all about my thinking and the processes I went through to solve issues for a hackathon challenge and it’s a bit long.  If you get bored and just want to check out the app this post is about, go ahead and jump to the bottom, I promise I won’t be offended!

This past week I took part in my first ever hackathon and it was definitely an eye opener for me! This event was held by MintBean and was actually a hiring event for jr. developers, which I feel is a great way to get noticed by hiring managers and recruiters but since this is my first one, I’ll have to wait and see how it turns out.

The event was set up so that any developer could join and even work in teams of up to three people for a single submission. At the moment of writing this post I’m still unemployed and looking for a job as a developer so I decided to tackle this challenge on my own in order to show off what I’m capable of myself. In the future I’ll probably work as part of a team when my situation has hopefully changed. The rules gave everyone 7 days to complete the challenge with the possibility of a grace period being added on towards the end. There were also no rules set for what programming languages or frameworks could be used except for a couple of game dev frameworks in order to give everyone a fair opportunity. Oh, and no direct copying and pasting or forking of working projects for obvious plagiarism reasons. The tasks for the challenge were simple and only needed to fulfill one of the following:

  • Users must be able to drag their mouse across the screen to make free-form lines.
  • Users must be able to click areas of the screen to fill them with a color, texture, or pattern.

Optional challenge – Add a full-stack feature that makes sense for your app. Functionality examples:

  • Allow users to save their art
  • Allow users to share their art
  • Build user profiles with galleries of their work

Other than that, it was game on!

First thing’s first: my initial idea failed and failed fast! Since completing my coding bootcamp I’ve been learning React in-between searching and applying for jobs. I’ve learned a lot about React and have built some -mostly- functional apps, including one that saves and pulls from a non-relational database. I decided to try building a Python Django app while using React for the front-end for this challenge. ...It did not go well.  By the second day I was pulling my hair out because I kept writing code for the React front-end that basically broke the app again and again with each piece I added. So, I decided to stick with what I know. Hey, I LOVE learning and playing with new languages, code, and techniques but let’s face the facts…I really need a job, so I stopped and took a breather for the rest of the second day.

On day three I refocused, scrapped the React front-end, and began building out the new front-end using the Django templating engine and JavaScript. I knew mine wouldn’t be as responsive or pretty as other apps using React, but I decided to focus on my strengths – the back-end!  Not that back-end, get your head out of the gutter! Building a simple front-end and making it interactive turned out to be only slightly challenging. I used the Canvas API that comes included in JavaScript (that was handy!) and started with a brush, eraser, color picker, brush size slider, and clear canvas as the initial tools. 

Once the front-end was up and functional I started working on the backend. Everything was running smoothly for a while; the login and registration features were something I’ve done many times before and setting up the database was a breeze. Then I hit a wall with the save feature.  Uploading an image and saving it on the back-end was easy enough, there are tons of examples and tutorials for that. Trying to convert a canvas element and everything on it to an image file and passing it to the back-end is not so easy apparently. I spent some long hours on the fourth day trying to make that work. Initially, I tried passing it with AJAX, converting it to dataURI and passing it with a POST command but couldn’t seem to get it to work! From there I decided to try passing it through a form. I learned that I could convert the canvas to a blob, save it as a temporary file, attach it as a file to a form and then submit it that way. It was all great in theory until I couldn’t get the form’s submit function to wait for the file to finish being attached! 

Workarounds! It’s how things get done in a pinch! Yeah, I know, it’s not the best, but I couldn’t get anything else to work, and yes, I tried async/await, and even tried coding it as a promise, but it wanted to be stubborn! I set up a JavaScript function to prep the canvas and attach it to the form as a file without submitting the form, then I tried to pull the form contents only to find that the form's file value was undefined. After some trial-and-error I realized that if I ran a function to prepare and attach the file twice, the form would recognize it and submitting actually worked! So that’s how I set up the save feature for the app. On the screen the user just sees that they have to update the file with the name they enter first before they can save it.  Once updated, the Update Name button swaps out with a Save button and the user can save it. Success!!! Time for a break, caffeine, and some Ibuprofen!

Things started moving along again for a brief period while I set up the Recent Activity, Personal Gallery, and User Profile features – all things I’ve done in the past. Experience and old projects for the win! My elation was short-lived, however, as I came to my next challenge: editing saved files. The issues I ran into aren’t actually what you'd think they would be. Loading a saved file to the canvas was actually super simple! It was saving the changes afterwards that was the big hurdle. Initially, when I would save an edited file, it would be saved as a copy with the user-entered name remaining the same and the file name being adjusted automatically so it didn’t overwrite any previous files.  This would be fine if not for the accumulation of duplicate files quickly eating up drive space. On a home machine, that can be overlooked, but server space is expensive! My first thought was to write a function on the back-end that would just delete the old file and then save the new one, but that seemed clunky and I felt like it had the potential to cause issues. Turns out, this is exactly what other developers were doing! That was easy! 

Except, it wasn’t so easy. The images were no longer being duplicated but the database entries mapping the images to each user and the image ids were! I was now getting multiple database entries all with the same image name, file name, and file path! This one took less time to figure out than the initial saving issue, but there was still a lot of trial-and-error. I was using Django’s built-in Forms and passing the image model as a Model form, pulling the model fields to automatically generate the form fields and using the built-in validation that comes with. Everyone catch all that? Super! Except it all had to be wiped out! So long simple auto-form-generator. I converted this into a custom form, built the form fields to match the model fields it corresponded with and then built a form validation function to clean the data that was passed through.

Once I updated all of that all I had left was to figure out how to stop the front-end from reloading and presenting the user with a blank canvas after they saved their file. Pulling the UID for existing files being edited was simple enough, I was able to fix that pretty quickly, it was reloading the canvas with an image file that had just been created and didn’t have a UID already stored in memory that presented the challenge. This one was actually a bonehead moment on my part. I spent a couple of hours trying different solutions to no avail before I had a “duh!” moment. The solution was so simple that it hadn’t even crossed my mind! A user has to be logged in to save their work and their UID is saved to memory when the canvas loads. So why wasn’t I just filtering the saved database entries on the user’s UID and the latest created entry?? Saved by best practices!!! Best practices people! Use them! 15 years ago I probably would have mocked myself for saying that, but always adding a table field for created_at and updated_at for every single table has saved me on many occasions! Thank you, Will from Coding Dojo!!!

So, here’s where I’m at now. A fully functioning full-stack web painting application with minimal bugs ready to be submitted for the hackathon.  If you’ve read all the way to this point (and you’re not someone I know) then wow, and thanks! I know my writing can’t be THAT good, especially with the given topic.  Anyways, feel free to check out the app! Hopefully this post scores me some extra points for the challenge as well.  Fingers crossed!  

https://github.com/GuardianBob/PaintApp

Jesse Meyer

Aspiring Full-Stack Developer

To view or add a comment, sign in

Others also viewed

Explore content categories