What’s in this post

Review

I’ve completed the Front End Libaries Certification on FreeCodeCamp.org. FCC claims that it takes 300 hours to complete. I estimate it took about 70 hours to work my way through it. The course goes through Bootstrap, jQuery, Sass, React, Redux, and React-Redux. It’s easy until the end. Concepts are introduced one at a time alongside a simple coding task which must be completed to progress. As long as you are reading carefully and taking notes, the problems are a breeze. The final section is considerably more challenging, however. You are tasked with creating 5 responsive front end apps in React on codepen.io. Those apps must past unit tests conducted by the FCC script.

I take notes in Freeplane, a mind-mapping software. I’ll eventually make a post about how I maximize my usage of this powerful tool. It’s easily my most-used application. Here’s a screenshot from my FreeCodeCamp.org notes. I cannot stress enough how incredibly useful it is to efficiently reference back to what I’ve learned.

Update: Now that post exists

My notes: .png export from Freeplane

freeplane screenshot

Adding those projects to this website

I wanted to include those projects on this blog, and not just with a link to my codepen. I used this tutorial from Dmitry Rogozhny’s blog to get started. Basically, I added yaml front matter to this post which describes external javascript resources that need to be loaded. In this case, React and JQuery. As my header is built, it inserts a <link> element for those resources based on my front matter.

The CSS styling was done in SCSS. Jekyll doesn’t load that up by default. There’s probably a Gem I could install, but instead I used a scss to css converter.

My script used Babel preprocessing for the React syntax, because writing React without JSX seems like a total drag. That meant I had to convert it to regular javascript in order to be able to include it as a <script> tag in this page. I followed these instructions on the babel.js site and used npx and the command line to generate regular javascript.

The cli in a directory with each of my files was:

npm init
npm install @babel/core @babel/cli @babel/plugin-transform-react-jsk
npx babel drum-machine.js --out-file dist/drum-machine.js --plugins=@babel/plugin-transform-react-jsx

To insert the script in the page, I created a very small include, called snippet-in-page.html.

 
<script type="text/javascript" src="{{site.baseurl}}/assets/js/snippets/{{ include.content }}"></script>
 

In this markdown file, I added a simple include and passed the name of the file as the content parameter.

 
<!-- calculator-root is just the DOM entry point for the script-->
<div id = "calculator-root"></div>
{% include snippet-in-page.html content="calculator.js" %}
 

Then I just threw my code in assets/js/snippets and included them as needed in this page!

A Calculator

This was the hardest project. Input validation is accomplished by regexes, as is the tokenization process by which the calculator “processor” object parses the string to perform its calculation.

Here’s a snippet:

let tokens = []; 
let token_finder = /(\-?\d+(\.\d+)?)|([\+*\/])/g;
let results = [...str.matchAll(token_finder)];
for(let i = 0; i < results.length; i++ ) {
    let r = convert(results[i][0]);
    if(r<0) {
        if(i<1) {
            tokens.push(0);
            tokens.push('+');
        }
        else {
            let last = tokens[tokens.length - 1];
            if(typeof last != typeof 'string') {
                tokens.push('+');
            }
        }
    }   
    tokens.push(r);       
}

Explanation:

  1. An empty array for final tokens is initialized.
  2. The regex token_finder finds two groups, either numbers which may or may not have a leading negative sign and may or may not have decimal values or one of the operator signs (+,-,/,*) and the matches are put into an array called results.
  3. A for loop iterates over the results.
    1. A “convert” function is called on a result to turn it into a number or float if it’s a number or float.
    2. If it’s a number and negative:
      • If it’s the first iteration, 0 and “+” are pushed to the tokens array.
      • If it’s not the first iteration, and the token preceding this one is not an operator, a “+” is pushed to the tokens array.
    3. The result is pushed to the tokens array.

That’s how this calculator can accurately deal with inputs like "5*-3", "5-3", and "-5+3".

The calculator has one major bug that I just noticed. It displays “NaN” if the equation ends in a number. That’s something to fix another time!

A Drum Machine

Credit to Marcus Connor for the CSS toggle buttons I used for the nifty switches on this drum machine. I originally found those toggles while browsing freefrontend.com.

For a future js sound project, I’ll to check out a library like howler.js to see if I can do better with audio than javascript’s regular <audio> tag. This Drum Machine works, I guess, and passed FCC’s tests, but the clips cut themselves off and don’t play reliably.

This was a decently tricky project, just because there were a lot of moving parts. I think it had the most separate React components out of any of these.

25-5 Timer

There are definitely some libraries out there I could have used to make this timer more accurate, as javascripts setInterval seconds aren’t exactly seconds. At least it saves me from having to include even more javascript on this page. I tried to make this one look a bit like a stopwatch. I used Microsoft PowerToys Color Picker to grab various colors from a stopwatch reference photo and cssgradient.io to make a couple gradients. I don’t love the interface on that site though, and I’ll be on the lookout for another gradient generator next time.

This was the final project in the series and it took forever to pass the last test. Couldn’t figure out what I was doing wrong. Turns out, I wasn’t prepending a “0” to my seconds and minutes, which the tester wanted. The timer should, of course, display 01:05 not 1:5. Sometimes it’s the little things that get ya!


Random Quote Generator

This was the first project of the bunch. It was fun because it was the first time I called an external api with the ajax feature. I’m looking forward to finding other apis, or even making one of my own. I recently wrote a scraper that uses puppeteer to gather games on the jeopardy archive into .csvs for importing with Anki. It would be pretty cool if I could leverage that into an API that would spit back random jeopardy questions instead of random quotes. Only issue is, figuring out what copyright issues I might run in to with that. Might have to send out some exploratory emails before I try putting something like that into production.

Another stumbling block I ran across here was the twitter icon. Originally, I used bootstrap to quickly grab an icon, and that works great, but as I was bringing that codepen onto this blog post, I decided I didn’t want to add another big include, since I only used one class in the entire bootstrap repo. I know there’s a way bootstrap can compile you a small version with only what you need, but I didn’t want to go through all that for one lousy little twitter icon. Instead, I went and found an SVG of the twitter icon and put that right in my code. React doesn’t render SVG elements without additional libraries, however, so I had to insert the SVG as innerHTML into the link after it loaded.

I used a lifecycle function for that.

componentDidMount() {
      //for adding an svg to twitter <a>
      document.getElementById("tweet-quote").innerHTML = `<div id="twitter-image-wrap"><svg>...</svg></div>`;
}


Markdown Previewer

I used an external script to help with this one, marked.js, which made it really straightforward. Basically, you just call “marked(str)” and it transforms markdown into html elements. Couldn’t be simpler.

All it came down to was:

$("#preview").html(marked(event.target.value));

In the onChanged() callback for the text area.


Looks like some of the minimus CSS on this page and the stuff I stuffed in for these snippets are interfering with each other. Why did I have to get so fancy with my CSS when I was writing these?! I also thought it would be cool if the textarea expanded its column size depending on the page size, but that’s come out all kinds of weird. Yet another thing to fix up in the future!

Summary

These projects were excellent challenges, perfectly appropriate for my skill level. They were great opportunities to practice javascript, CSS, and use many features of different libraries. I explored regular expressions, React’s lifecycle methods, ajax API calls, and more. However, I got the most satisfaction out of the work I did integrating those projects into this page. It is extremely satisfying to envision a page an build it. I really like Jekyll, Liquid, yaml front matter, and this system for creating blogs. I look forward to heavily customizing this site in the future. Ruby is extremely elegant and straightforward, and I hope to be able to devote more time investigating it in the future.

So out of all this code, the most satisfying for me was the very short include I wrote, snippet-in-page.html, described here. I’ll definitely be re-using that to take full advantage of the Jekyll / Liquid setup and plug all sorts of little utilities around my page. Next up is likely going to be a “top” button, that takes you back to the start of whatever page you’re on.

I’m getting a lot out of FreeCodeCamp. I’m going to keep going with it. Next up is the Data Visualization Certification which looks to be focused on D3. That’s more exciting to me than React.

Plus, FreeCodeCamp.org offers certifications that show up on your linkedin.

FreeCodeCamp.org certification as it appears on LinkedIn

That’ll look nice with a Bachelor’s Degree beside it. Maybe I’ll make a hefty donation to FCC, as soon as I’m employed.