Hackterms, Pt I

Laying in bed at night a few months ago, an idea came to me: Urban Dictionary for code.

Countless times, I’ve google how to do something, only to be bombarded by opinions and definitions for related tools. I’d google Rails and be told that I should use SQLite instead of Postgres, and that MVC is on decline and I should hook up to an MV * front end framework, and that I should install some NPM packages (but… Rails uses gems?) and so on. By the end of it, I’d be left confused and overwhelmed. My well-meaning dev friends weren’t much help – they’d dive into the complex of the topics, debating the performance merits of tools whose purpose was beyond me. I felt dumb. I just wanted to know a few things:

  • high level, what does this do?
  • how does this tool connect with everything else I’m building
  • is this worth learning right now?

A few days passed, and the idea nudged me again. I decided to share it with two subreddits – r/webdev, and r/learnprogramming. Reddit is fickle, and something interesting happened. r/learnprogramming gave me a score of 0 and a few cautionary comments, warning me this wouldn’t be useful.

Screen Shot 2017-09-25 at 9.06.19 AM

r/webdev on the other hand… said “hell yes”. I got a lot of really encouraging responses, and a spirited debate on the merits of such a tool.

Screen Shot 2017-09-25 at 9.05.10 AM

I knew I didn’t have a moment to lose. With such an overwhelming response, I had to build this thing. I was excited and more than a bit nervous – after all, r/webdev is a community of developers (though also more than a few learners!) Users also brought up some great concerns about the accuracy of oversimplified definitions, trolling, and similar resources.

Nevertheless, hundreds of real people had a passionate, largely positive response to my idea, and I was pumped. I set up a Trello board and started wireframing.

Screen Shot 2017-09-25 at 11.08.28 AM

Not pictured: fear and ambiguity

After QRL, I was fairly confident I could get at least an MVP of the app up – but this app was going to be entirely driven by the community, with visitors contributing to definitions (and ideally moderating.) The top comment was – open source this. I had no idea how.

* *  *

First attempt at instant search

I built the initial website with the core features – the ability to search and add new terms and definitions – pretty quickly. I also implemented my best attempt at “instant search”, sending a regex-powered request for similar terms after every single letter the user types. This was a fun mix of front-end design and coming up with a sorting algorithm.

Voting was a little trickier, but I managed to create a clone of a Reddit/Stack Overflow type upvote/downvote system.

Next, I turned to the user profiles and well as moderation tools. I wanted to create a minimal barrier to creating new definitions to deter lazy trolls and very casual users from cluttering up the websites. So, I decided that similar to reddit and Stack Overflow, anyone could vote on definitions, but users would need to log on to add new definitions. I wanted to keep accounts as slim as possible, so I created a reddit-style, minimal signup workflow – just a username and a password. No email confirmation, or password confirmation – at least not until the website got some users.

First attempt at signing up. Missing: password reset

I also implemented bcrypt, and finally started to thoroughly understand how hashing, and salting works. In the past, I’ve used the Rails gem (thank you, Michael Hartl!) but it never fully clicked. Now, hello, secure passwords!

Working on the front end made me really want to use components and nudged me to finally learn React (which I’m going to do next.) In the meanwhile, I learned to use Handlebars.js side by side with jQuery. This allowed me to move my definitions into a separate HTML file instead of jQuery-appending an incomprehensible string of HTML.

This also massively helped with the Admin board I set up next. I wanted to initially moderate submissions (again, to have a little control over the quality of the content), so I set up a system where I – or a moderator – would need to approve the first 5 submissions for every user, after which a user will have earned the websites trust, and could add endless definitions immediately. I figured, again, that this would deter the lazy trolls from making endless accounts to spam.

I spent a lot of time thinking about the relationship between quality control and the user-generated nature of the site. At this point, I had no idea how I’d moderate, or what standards I’d even set in place. I was okay with the idea of not-100%-correct definitions (and definitely wouldn’t be able to judge the quality of all the different CS topics), but I wanted to make sure that every definition on the site at least made an effort. I didn’t want the content to become heavily subjective, opinionated, or devolve into in-jokes. Moreover, I wanted to prevent posts unrelated to programming. I had described the site as an “Urban Dictionary for code”, drawn drawn to the “in-the-loop” nature of Urban Dictionary posters – not its vulgar, in-joke culture.

At this point, I wasn’t worried about the side getting flooded with trolls bent on posting offensive content – I didn’t think I’d ever be that popular. Rather, I was concerned about low-effort, inside-joke, trashy content (ex: “Rails is the sexiest disaster from 2004″)

* * *

A week in, my project was coming along nicely, and I had finished the core features and admin board. The last MVP feature left to build was comments – and I had some ideas for a cool, post-MVP way to improve these into a helpful, unique feature.

I was really grateful for my Trello board – it kept me on track, and I always knew what to do next. Whenever I got new ideas (which happened very often) or noticed bugs that weren’t worth fixing immediately, I’d just add them to the board and prioritize them, freeing up my mind to focus on the highest priority stuff. I noticed my mind wandering and darting between parts of the app a lot, so it was really helpful to turn to my board. It was also gratifying to see how much I had already done (despite how much work was left).

My Trello board, a week in.

Next up, I had two tasks that intimidated me:

  1. defining my post philosophy and guidelines (“what should ideal content look like”?)
  2. coming up with the website design.

* * *

Around this time, I began to get lost in my own project. In a rush to get things up and running, I coded quickly. That’s not to say I had no structure – in fact, I created my Trello board and schema precisely to know what I’d need to code next. However, I was now far enough into my project that my highest priorities weren’t always blatantly obvious, and I was faced with a lot of “important-but-not-crucial” tasks. I had prioritized my work into “must have/important/nice to have/not crucial” tasks, and I’ve built all the “must have” tasks. That is, I finished all the things that were absolutely crucial for the website to get off the ground. Users could search for definitions, vote, and add new definitions. I had set up a database, and deployed the site. Now, I needed to get through all my “important” tasks – things that were pretty crucial to a good experience, but not essential for the website to run – comments, notifications, mobile design, password reset, moderation, etc.

I found myself struggling to pick what to work on, and often reverting to small design fixes to feel like I was doing something, all while avoiding tackling the next big feature. Beyond a lack of prioritization, certain tasks (like adding notifications when a new term submission was approved or rejected, for example) mean that I needed to dive into the less-than-ideal structure I had set up.

The lesson seemed to be: prioritize harder, and plan ahead further. I kept seeing how important my Trello board/schema/wireframes were during the design process. As a friend described the process, I had consciously taken off my product and project manager hat, and put on my developer hat – and as a developer, I didn’t want to think about prioritization. I just wanted to code and solve technical problems.

That’s not to say I didn’t see this coming – I knew planning was important, which is why I tried to plan ahead to begin with. What I was discovering is that it planning was crucial, and I’d surely plan even more in my next project.

* * *

I had to constantly remind myself I was building an MVP, that I needed to get this to users as quickly as I could, and then learn from their feedback, not my impulses. Around this time, James helped focus me by reminding me that my job was to get out barebone versions of the crucial features, not polished versions of some features. I would often find myself digging deep into something obscure, like updating text fields on login without refreshing the page – inconveniences the early adopters would surely forgive me for – while ignoring tricky-but-crucial features, like password reset.

I also tried to keep impostor syndrome at bay. I was building an app with Express and jQuery,  with no front-end framework, no Mongoose, no ES6, with callback hell in my code – in short, with a million opportunities to stop and write better, fancier code with newer technologies.

Finally, I got the app to a place I was happy with it. The big test was simple: would users like this? If they did, I could spend more time with it and improve it based on their feedback. If they didn’t, I’d move on to something else – like learning a fancy front-end framework, Mongoose, and ES6.

The next step was exciting, but also new territory – getting beta users and seeding the site with definitions.

* * *

At this point, I showed the website to my girlfiriend Jenn and my friend James. They were the first to see the site, and it was immensely gratifying to watch someone go through it as a user would. Both found a number of bugs and inconsistencies, and were confused by a few of the same features, which was very helpful. James also noted that the website UI felt old and looked like a classic dictionary, counter to the product I was trying to build – a dictionary of cutting edge tech terms.

I now had two Trello cards full of bugs to patch and revisions to make, as well as a design makeover to tackle. The design bit concerned me, because design is not my forte, and I wasn’t sure how to revise it.  I’d love to say that I jumped back in and fixed everything, but in truth, I was frustrated and sad. I wanted my product to be perfect right off the factory floor, and it was far from it – even to the people closest to me (whose job was, of course, to be brutally honest). Discouraged, I took two days off and tried not to think about code.

* * *

Although it stung at first, my session with James was very helpful. He pointed to a few design elements that felt outdated – but more importantly, I started really paying attention to the websites I visited. Normally, I’d pull something up in the inspector if it caught my attention. Now, anytasdfime a website struck me as sleek or modern, I would pause and try to zero in on the elements and aesthetic that created this feeling. I’d then open up the Dev Tools and dig into why. I knew that I had made timid color choices – not knowing what to pick, I stuck to a few shades of green, beige, and brown. So, I tried to make the colors bolder. I paid attention to the way others use box-shadow and gradients, thin fonts, icons (at James’s suggestion).

giphy

UI, Take 2

At the same time, I wanted the site to be as fluid, unobtrusive, and undemanding of the user as possible. Nobody likes making accounts; nobody likes long surveys; nobody likes long load times. I wanted to get to the point and give the users what they came for – definitions, with no fluff. Inspired by Reddit’s outdated-but-straight-to-the-point design, I tried to cut out as much of this fluff as possible. Attention on the internet is precious, and a cute cat video is just a click away. My job was to eliminate any friction.

* * *

Six weeks later, I got to a point where the website was 99.5% done, and I knew I needed to launch it. I did 60% of the work in the first two weeks, and the last four were a mix of adding secondary features, obsessing over minor design elements, and not working with enough focus.

I knew I had to launch the site, because from here on, any further features would be dictated by my users. I had been avoiding this for weeks. James always suggested I was good at the “marketing” bit of things, but the truth is, I had no idea where to start. I did however, know that…

  • my idea seemed to get good traction, which is why I set out to build it
  • it’s better to have something out in the world with a few users than sitting in the drawer
  • I needed to move on. I’d either be working on Hackterms a while longer, or it’d flop, and I’d move on to something else – but I needed to know

I was sure that more people would show up to the site looking for definitions than to add them, so I needed to seed the site with some starting definitions – and get others to, because I’m not qualified to teach the world to code – before announcing Hackterms to the world at large. Splitting the site into a soft launch stage and a  hard launch would also allow me to effectively beta-test with anyone willing to try the site out.

I started with the low-hanging fruit. When I made my original reddit post, a whole bunch of users agreed to help. I reached out to them. I thought about their incentives, and what I could do to help motivate them – given my past work in crowdfunding, I thought about the best rewards. My contributors would be sacrificing their time, motivated by a desire to give back to the community. So, I needed to recognize their good motives. A small token, like a handwritten postcard, seemed like the easiest move (although that required getting the users’ addresses…). I also considered adding a badge to the site, but have always found these a little gimmicky. Finally, I knew I wanted to foster a sense of community amongst the contributors, so I started a Slack channel and created a subreddit, just in case.

I went back and re-read the Reddit thread, parsing 38 usernames of people who wanted to contribute. Next, I put together a Google doc of the top terms I’d want defined. A commenter suggested I use this roadmap as a starting point.

I was anxious to reach out to people. I thought of a dozen reasons Hackterms might fail; and of objections that people might raise to the site’s existence and purpose. I thought about the alternative resources available to developers: Wikipedia, StackOverflow, MDN, countless coding tutorials, FreeCodeCamp, you name it.

Nevertheless, I built Hackterms, and I believed in it, and Redditors thought this tool should exist. I had nothing to fear but the sting of rejection, and if I failed, well, at least I would have tried. I knew I’d be better off saying “I built something and put it out there” than “I built something and never went anywhere with it.”

I settled on a simple pitch – Hackterms was going to be the “why”, “where”, and “when” (importantly, not the “how”) of coding terminology. So, I took a deep breath, and reached out to the first 10 users.

Hey [user],

About a month ago, I shared an idea for a dictionary of coding terms and you offered to help. Well, I’m excited to tell you that I’ve spent the last month building the site, and could now use your help!

In order to launch, we’ll need to have well-written seed definitions for common programming terms to attract initial users and get the ball rolling. Would you still be interested in creating an account and writing a few short definitions for common tools/concepts you use as a developer? Early users such as yourself will help set the tone and shape a direction for the site, and I’ll send you a vintage NYC postcard to thank you for your time (and swag down the road, if things go well!)

Let me know if you’re interested – hoping to work together on this!

~ Max

* * *

I ended the day with just one user, but 6/10 (!) people responded positively. The next morning, I woke up to 3 users. The feeling of seeing people sign up for my thing – trust me with their accounts and their time – and seeing the supportive messages – is incredible. Users were also adding great definitions. I quickly threw together a metrics page to track how many users and definitions I was getting. I also had a few people join a Slack team I created. Messages like this kept me going, despite the fact that I was intimidated  every step of the way by the fact that most contributors were probably way more knowledgeable than me. A scary thing about coding for me has always been that there are so many ways to do something, and I’ve always worried that the way I’m building isn’t the best or most correct way. Still,

Four or five days later, I was nearing 15 users and ~50 definitions, and had nearly exhausted my initial list of 38 redditors. I wasn’t sure how many to aim for, but wanted to fill the site with enough definitions for the most commonly searched terms before launching – perhaps 100? 200?

I made a few valuable observations, and it felt amazing to learn from users, not my own intuition.

  1. A bunch of new accounts only made one definition. Although I was approving them as quickly as possible (checking for new submissions incessantly), I thought that not immediately seeing their submissions must have turned these users off. James had suggested approving first and moderating later, so that’s what I did. I worked hard on my submission queue, but that didn’t matter. I turned it off, and auto-approved all definitions, at least while I could manage submissions.
  2. Users who added new definitions used the “related feature” field almost every time, and then followed these to add new definitions. They seemed to naturally follow a train of thought about a particular area of coding. I did this as well – I added “JSON”, and then “AJAX” followed naturally.

A week after that, I crossed 50 terms with almost 60 definitions. I also got a great code review and design pointers from my friend Esther. From here on, I knew I needed to generally refactor the code to avoid callback hell, add the ability to edit definitions, and most importantly – I needed more users.

Screen Shot 2017-11-27 at 11.37.27 PM

UI, Take 3

But, I had gotten Hackterms off the ground. It was my first real user project since TheyGotFit, and it was live, and it was being used by real people – by strangers on the internet.

I stepped back and thought about getting more definitions, as well as a real public launch. More on that in Part II, hopefully soon.

Advertisements

Keycode 229

I ran into a pretty obscure mobile JS error, and thought I should share it, on the off-chance someone else finds it as well.

I had built a click event attached to key codes corresponding to letters and numbers – so, when the user hit a letter, punctuation, or number, my event would fire.

if((e.which = 48  e.which = 90) || etc...){

This worked wonderfully until I tested on Android. My event wasn’t firing. It was working in DevTools mobile view, but not on my phone. Worse yet, there’s no easy way to see a console on mobile, so I resorted to appending console.log messages right onto my live site (since I couldn’t run localhost:3000 on mobile). Not pretty.

Anyway, I got to the root of the issue. Every key on mobile was registering as

e.which == 229

This wasn’t happening on mobile view on DevTools because the key codes were being read correctly. Turns out this is a well known issue. My solution was simple – to fire the event on e.which == 229. However, this didn’t actually give me the key code.

It seems like there’s no ideal solution. Some people suggest using a keypress and textInput listeners, which works intermittently. There is also this workaround, which involves getting the last character typed in a field and determining its char code (a number representing a Unicode character, found through the keypress listener), not key code (a number representing the key on the keyboard the user pressed, found through the keydown/keyup listener). Here’s a neat tool to differentiate.

Here’s the jQuery solution, though I think you can accomplish the same thing by using a keypress listener.

var text = $("#some-textarea").val();
var keyCode = text.charCodeAt(text[text.length - 1]);

 

Little Annoyances

I am dealing with a set of small front-end problems that’s driving me crazy. I’m trying to integrate instant search, and every time I change a small bit of code, it stops behaving as I expect it to.

These individual problems are not hard, but digging through my (messy) front end structure to fix them a chore and a motivation killer. Every time I run into another one, I want to throw my hands up and turn to something distracting – which completely kills my productivity

I need to learn to recognize and ruthlessly prioritize issues like these. In the structure of my app, these issues are not important, and should be dealt with when I work on the front end design – not while I’m trying to build out the back-end structure. Sure, it’s annoying to see the issues pop up every time I try to test the app, but I need to compartmentalize and move on.

When these little annoying issues accumulate, they can be major motivation killers – but only if I let them.

I just need to remember: “There will be time to fix these. I will deal with them – later.”

Handlebars + jQuery

Goal: add HTML components using jQuery without writing a whole bunch of HTML as a string. Instead, we’ll store HTML components in their own files, to be recycled as needed.

Old solution: 

$("#element").append("
<div><span class='myClass' id='" + relevantId + "'>" + relevantID + "</span>Some text about " + jsVariable + " element</div>
”)

Better solution: 

React.js has been been on my “to learn” list for far too long, and I swear I’m going to tackle in next – I think (hope) that it’ll solve my components issue.

Meanwhile, however, I’ve had to get around with jQuery, and have been running into a more and more persistent problem. Appending HTML with jQuery is easy for small bits of code, but ridiculous for larger snippets or components. Fortunately, I just found a solution: Handlebars.js, a front-end templating engine. We’re going to store our HTML snippets/components in their own files, and inject variables as needed. So, if we’re coding a Twitter clone, each post would be built from a post.html file, with relevant data inserted from JS using {{variable}}. Our files will look like this (sorry about the screenshot – WordPress formatting sucks)

Screen Shot 2017-09-28 at 4.31.37 PM

Handlebars will compile these HTML files with the variables we’ll provide it with. By the way, if this is looking familiar, it’s because it’s how things work in Angular and React, too (as far as I’ve seen), but we’re implementing it without the massive learning curve or intensity of using a whole front-end framework.

So, let’s get down to business. Here’s the step by step:

1. Add a Handlebars CDN link to your HTML file. Grab the latest version here. I recommend the handlebars.min.js file, since it’s a little smaller. Add the file in a ​script tag, before jQuery and your own JS script.

2. Create a .html component file following the convention above, inserting variables with this format: {{var}}. You can also use a bunch of other pre-built Handlebars conventions outlined in the documentation. I’ll call this file component.html.

3. Now, we’re gonna need to fetch the contents of the HTML file in your JS script. You can do this using jQuery’s $.get() method. The code will look like this:

$.get("component.html", function(data) {
  // do something with the data here...
}, 'html')

4. Next, a bit of Handlebars magic – this should go inside the function(data).

Note: function(data) is a callback function – it’s only run once $.get() fetches the contents of the external file. Because JS is asynchronous in nature, it will continue to run code written the $.get() section as the app waits for the $.get() to return the data from an external resource (in our case, a file).  So, in order to operate on the data after we fetch it, we pass in a callback function with the data as a parameter.

 var myTemplate = Handlebars.compile(data);

// this is where we store our variables
var context= {
 "name": "Biz Stone",
 "post": "I am a very important person at Twitter"
 };

// Handlebars magic injects our variables into our template
var compiledPost = myTemplate(context);

// this should look familiar
$("#postSection").append(compiledPost);

5. Voila! We’ve now appended a whole HTML snipped with our own variables. No more messy strings in our JS/jQuery code.

PS: With a little patience and regex string manipulation, it’s possible to get rid of Handlebars altogether and search the $.get() html response for variables encased in {{ }}, replacing them with your own values. However, for the sake of speed, I leave that exercise to the reader.

Building a Starfield with Canvas

I’ve played around with HTML canvas before, and have even made a field of twinkling stars. However, this time, I wanted to recreate an old Windows screensaver where you fly through a star field. In short, something like this.

This proved to be harder than I expected. My first real attempt had stars increasing in size and velocity as they got further from the center.

starfield1.gif

First attempt

The problem with that is that no stars don’t seem to move towards us, just off the side of the screen – so, I’ve essentially created a particle emitter. You’re watching stars be created far in the distance, and the sense of depth comes from the changing star size as they get closer to the edge of the screen.

This wasn’t good enough. I wanted each star to actually occupy a position in 3D space, and then have this position be reflected in the view, creating a more realistic simulation. I wanted to create a sense of a star coming right at you. The issue is that stars have to come off the screen eventually no matter what – so, as a star gets closer to you, it needs to (1) increase in size and (2) move toward the edge of the screen

This really tripped me up for a few days. I couldn’t wrap my head around how I can represent 3D space in 2D. I was using the pythagorean theorem in 2D, using each star’s X and Y coordinates. I knew I needed to integrate depth, Z, but I wasn’t sure how. Then, after a few days, it hit me. I watched several working starfields closely to isolate what was happening, and I realized that a star’s distance from the origin point – the center, in my case – impacted two things:

  1. the size of the star (stars closer to the us appear larger)
  2. the speed with which the star travels (stars closer to us appear to move faster)

Then came the epiphany. Stars can only move along X & Y axes, but the speed with which they move implies their distance from us. 

Using this, I could now create a sense of depth. Two stars can occupy very close X & Y coordinates – sit next to each other – but if one is bigger and moves towards us faster, we perceive it as being much closer. It took me a bit of time to finagle the relationship between the Z coordinate and the star size/speed, but once I did – voila! The starfield looked much more realistic:

giphy

Second attempt (with depth)

So, how does it work? I created a star object with X, Y, and Z coordinates. At each screen refresh, I needed to change each star’s…. (1) x & y coordinates and (2) size, as determined by its Z coordinate.

(1) Each frame, I would get the distance between the star and the center, and would move 2000th of this – times the star’s Z coordinate (which is between 1 and 100+). Thus, stars with higher Z coordinates – which means the star is closer to us – would move off the screen faster.

(2) A star’s size would similarly grow as the star’s Z coordinate increased, and the star got closer.

// each frame...

star.size = 0.2 + 0.038*star.z; 
// a star is always at least 0.2 px in radius + some fraction of 3.8, based on distance - 0.2-4px radius total

star.x += (star.x - center.x)/2000 * star.z; 
star.y += (star.y - center.y)/2000 * star.z;

star.z++;

It took me 4-5 days to come up with that relatively simple bit of code – to wrap my head around the relationship between a 2D screen and a 3D space. Once I did, I decided to gamify my new project. More on that soon!

Project: Book vs. Movie

James and I have been looking to build something together and learn to collaborate better as programmers. James came up with a great idea: people often wonder which is better the book or the movie? So, we built a small app to find out.

Book vs. Movie queries the Goodreads API and the IMDB API to fetch movie metadata and rating, and displays them to the user, highlighting the winner.

We built the app with Node and Express, with some jQuery on the front end, sitting side by side at Think Coffee near NUY. This wasn’t our first collaboration, but it was the first time I’ve ever really pair programmed with anyone – we took turns writing code, both of us focused on the code in front of us. We both learned to work with a few different APIs and parse XML to JSON, but more importantly, I picked up a whole bunch of small techniques and tips on how we set up and build projects. James likes to use as few libraries/packages/external tools as possible, so we were both a bit out of our comfort zone – he was trying to thoroughly understand how the NPM packages and libraries that I picked up on the fly, and I was trying to use as few tools as possible, and really get what’s happening under the hood.

It was great to watch James work on the front end as well – something I’m not great at or feel as comfortable with. I learned about CSS animations, and picked up a few neat tricks

The main issue we ran into – that we chose to bypass for the sake of building faster – is that movie/book pairs often have different titles. A great next step would be giving the users an opportunity to tell us what movie pairings are correct – and then displaying these pairings first in future searches.

The end result is a finished – albeit simple – website, and a desire to build more. In the end, we hooked up the app to a Mongo DB to track incoming searches, and let it out into the big wide world. It feels good to build for people.

Recurse Center, not.

So, after an excited two weeks applying, I got rejected from the Recurse Center after my initial Skype interview (on stage 2/3). This is a bummer – I had gotten really excited about the idea, and thought it would have been a great fit. Getting rejected sucks, and I’m not going to try and turn this into some sort of a “this is meant to be” or “everything is just great” post – but I do want to reflect on the experience honestly.

One of my big worries is that this would have the perfect time for me to attend Recurse – it would have been a great environment in which to grow as a developer and soak up the skills I want to and need to learn. My path now is harder – I’ll continue learning and building on my own , and if I’m still free in three-four months (and can afford to be free for *another* 3-4 months), I’ll apply again. I’m worried that once I get a job, it’ll be a lot harder to find 3 months to attend.

Anyway, all in all, the application experience was smooth and a few good things that came out of it:

  1. Having a hard deadline pushed me to finish my personal website (which I had already been working on) and I wrote out a whole new small project for the application.
  2. I approached all the questions genuinely, and the application gave me a good structure in which to evaluate my programming abilities and my plans. For example, I got to plan out what I’d focus on learning in the next 3 months, and I thought about the kind of engineer I’d want to be in a few years.
  3. The overall process – the application, the website, the interviewer, the speed with which they responded – was fantastic.
  4. I made it through the first round, which is the first time someone objective (not a friend or co-worker or mentor) looked at my code, and gave it a pass.
  5. think I have an idea why I didn’t pass onto the final round. Of course, RC doesn’t offer feedback, so this is a guess – but I think it came down to my communication ability, particularly around the things I learn (I tried, poorly, to explain the JS event loop). This is frustrating, because I was involved in interviewing lots of people at Codecademy, and watched candidates flounder and ramble, and I knew this was a weakness of mine – and I still fell into the trap of doing it. I also didn’t have the most defined plan for what I wanted to learn, but I’m not sure if this held me back (I was given the advice of not proposing a project that’s too specific). So, while it’s frustrating to think about how I could have done better, at least I have an idea where I underperformed – and can focus on fixing it next time.
  6. If I do choose to reapply, there are a few people that have gotten in on their second try, and had a great experience.

Finally, and I think most importantly, I loved every hour I coded. While getting rejected stings, I jumped right back into my next project  the next day (more on that soon!). If I let this deter me, it was never the right move to begin with. So – onto my next project!

 

 

This is trouble

I’ve run into a bit of JS this trouble. Take a look a this dog object:

var dogs = [];

function Dog(name){
  this.name = name;

  this.bark = function(){
    console.log("Woof! My name is" + this.name);
  }
  this.friends = function(){
    dogs.forEach(function(dog){
      console.log("My name is " + this.name + " and I'm friends with " + dog.name);
    });
  }
}

ruffy = new Dog("ruffy");
rex = new Dog("rex");
spot = new Dog("spot");

dogs.push(ruffy, rex, spot);

ruffy.bark();
ruffy.friends();

When I run ruffy.bark(), I get Woof! My name is ruffy So, then, what would you expect the the result of ruffy.friends() to be? Here’s what I’m getting:

My name is undefined and I'm friends with ruffy
My name is undefined and I'm friends with rex
My name is undefined and I'm friends with spot

This was strange, because I figured this would refer to the object – after all, the same technique works for getting the dog’s name!

After a bit of console.log-ging, I’ve found that in bark() this refers to the Dog object, but within the forEach loop, this refers to the global variable. I’ve found a few fixes:

  1. use a for loop instead of a forEach loop
  2. use the ES6 for of loop
  3. create a variable to store this outside of the forEach  loop.
this.friends = function(){
  var self = this;                 // self == this, the object instance calling the method
  dogs.forEach(function(dog){
    console.log("My name is " + self.name + " and I'm friends with " + dog.name);
  });
}