How I made this SPA and what I learned doing it

Juliana Gomez
8 min readAug 2, 2017

--

I can’t say it enough: if you’re learning web development you need to build things! Without a doubt, I’ve picked up great ideas reading and researching. However, it’s when I’m challenged with difficult concepts within projects that I learn a lot and then I don’t easily forget the solution. So I’ve been building!

In my previous blog post, I walked you through how I made a responsive web page and what I learned doing it. Following that, I started thinking of what I could do next when the idea of an internet adventure was born. I knew that I wanted to play around with HTML5’s <video>, <audio> and <canvas> tags and since my last project I had picked up some cool new web development tricks. So here’s how I made this single page application that takes you on a wild (consensual) ride through the internet.

(By the way, here’s the repo and here’s the live version!)

A gif of the application in use

The Setup

My dear friend and mentor was generous with their time and knowledge to walk me through a configuration workshop that sets up a web server using Express (a Node.js framework) and sets up Webpack (a module bundler) for my projects. I could probably write an entire post on how I learned to set up my projects but for this one I’ll do a quick recap.

First, I set up the web server using Express and a quick google search for a template on how to do it. Then I installed Webpack and created “src” and “public” folders. “src” is where the files I work on will go and “public” is where Webpack will put them once it processes and bundles them up. The server will grab the files in “public” and that’s what it’ll serve to the browser.

This is kind of what Webpack does (giphy of Bart Simpson packing a suitcase with a fish tank)

With Webpack I used Babel, css-loader, file-loader, sass-loader, eslint and sass-lint. These loaders and compilers will take the code I write and the files I use and translate them into code that runs in the browser. For example, Babel takes ES6 and translates it to ES2015 while sass-loader takes Sass and translates it to CSS. The linters are a great tool that you can use right in your terminal that will point out syntax errors and can sometimes even automatically fix them for you.

Do I need to do all this on a project this small? Probably not. Will I do this set-up myself when I’m working on big projects with a team? Also probably not. But I did find learning this was valuable to get insight into how this part of setting up a project works and definitely worth the time and energy.

HTML

The HTML on this was really simple because I used JavaScript to create and remove elements dynamically as the user moves through the adventure.

I wanted to use a <video> tag but I realized that I’d have to use a video that I had downloaded previously so I used an embedded YouTube video using <iframe> instead. For the audio, I had to download the song I wanted, edit it using Audacity and configure the file loader to accept .wav files so I could pass it to my “public” folder for use. I can’t tell you how amazing I felt when I pressed play and the clip had made it to the “other side”. It was GLORIOUS!

I do this too when I listened to this song a million times a day (giphy of Macklemore riding a convertible with his grandmother, they both raise their hands in the air)

To use <canvas> I researched how to make a simple canvas to draw on and customized an answer that I found on StackOverflow to allow the user to draw a heart in red. I would’ve liked to create a function to erase and start over but that’ll come in a later project! Also of note: this canvas isn’t accessible because it’s only available to people with touchpads or mouses.

Gif of the canvas used to draw a heart at the end

CSS

I learned to use Sass! It’s super enjoyable and I love using variables. In a small project like this, I didn’t use a large colour palette but I can see this coming in handy in the future when working with various colours and fonts. I’d like to get more comfortable using mixins and start doing some calculations right in the scss file but I didn’t find either of these things were needed in this project so it’ll be on the list for things to try out soon!

For this project I used BEM and have to admit that I was a bit confused picking it up. After using it for a couple other projects since, I’ve gotten the hang of it though. For this project however, it was a good place to start because it uses a lot of reusable styles.

Beautiful! Variables, nesting, imports! (This is a screenshot of lines 1–20 of my scss file)

For the design, I cut right to the chase and grabbed suggested colour palettes and font combinations. I know that design is something that I have to work on and using already tried ideas has helped me solidify concepts and make applications that are much prettier. No shame in admitting that I need practice!

JavaScript

I made this application twice. The first time I hard coded all the HTML and made everything toggle using classes with display: none and display: block. When I showed it to my mentor, they made a small comment that I could have created elements dynamically using JavaScript. After they said that, I couldn’t stop thinking about it. I knew that it’d teach me things that I didn’t know so the day after I refactored the application to create elements dynamically.

As per usual, I made everything work well and then I took a look at my code and made abstractions. I realized I was creating a lot of buttons and creating a lot of elements so I created helper functions which cut down on a lot of repeated lines of code.

These are my helper functions, they create buttons and elements dynamically (screenshot of lines 7–22 of my JavaScript file)

This is the first project I’ve made where I assign the values that functions return to variables so I can continue using the value within the parent function. You’ll see it where I create elements and then need to continue using the element to add attributes or change texts. This is what I mean when I say you need to build things. I’m sure I’ve read about assigning values from functions to variables but it wasn’t a concrete concept in my mind until I actually had to do it.

This function uses two helper functions, assigns the value of createElement to a const video and then continues using video to add attributes (this is a screenshot of lines 70–80 of my JavaScript file)

Also in this project is my first .focus(). This is something that I picked up from my Udacity accessibility course and not only does it make my app more accessible (takes the user where they need to go next), I also needed it to bring the user down to a part that wasn’t displaying unless they scrolled down on desktop. I’m proud that this app is very usable on keyboard only but when I tested it with ChromeVox I realized that a screen reader can’t grab the headings, that’s something that would need to be fixed.

Look at that scroll down, thanks .focus()! (screenshot of my app)

Deploying to Heroku

I’ve been deploying projects to heroku but I hadn’t deployed anything as intricate as this before. I didn’t expect it to be difficult but the first couple of times that I tried pushing it, it kept throwing errors. I googled the error codes, tried fidgeting around but nothing was working. Mentors to the rescue (honestly, mentorship is so so so important)! My mentor and I looked it over and it turns out that one of the google responses that I didn’t want to try was the thing that worked! I’m still a little hesitant to try new things because I’m scared that I’ll break things but this experience taught me that I should give things a shot. Where’s the line between trying something new and not understanding it though (serious question, please answer in the comments)?!

This is how I felt when my upload was failing (gif of a dog running in between poles of an obstacle course and smacking their face on the last one)

The reason the upload wasn’t working was because I had all my loaders and compilers as devDependencies so when I tried uploading the project to Heroku, it wasn’t compiling properly and Heroku didn’t have anything to serve. Using NPM_CONFIG_PRODUCTION: false I was able to install the devDependencies so that Heroku could access the compiled modules and the project uploaded successfully. This isn’t a perfect solution and it’s not the best approach if you want to fix this in the long term. The ideal solution is to upload just the code that you need to serve from production but I couldn’t do it because I configured Heroku to take my entire project from git and I have my public folder ignored in git. Next time!

Next steps

This was a really fun project because I got to show a bit of my quirky personality and I chose techniques that I wanted to practice or learn more about. If you check out the source code, you’ll see that I have Jest installed in the devDependencies but I don’t actually use any tests. I need to learn testing so I can drive my development using tests. If you know any good beginner resources, please let me know below in the comments!

My next steps are learning React and getting a job! I’m looking for a company that is welcoming to folks who are starting out in their careers (ideally people who love to pair program and offer lots of learning opportunities) and where I can contribute my skills and grow to be a brilliant programmer. I’m really into the idea of growing with a company so I’m looking for a great place to land. If you have any leads, I’d love to chat!

Thanks as always to Sergio NS for your help teaching me the things, reviewing my code and reading over drafts of this post ❤

--

--