JavaScript and Regex: Using a regular expression and .replace() to strip (foo) from a string

Here’s a quick tutorial on using regular expressions in JavaScript to edit a string and return the modified result. My strings looked like this:

"Toyota (1999 - 2005)"
"Ford (1995 and up)"
"Honda (up to 2015)"
"Kia or Chevy (any)

In this case, each string was the name property on an object. (Ie: you’re not looking at an array of strings in the example above.)

For display purposes, I wanted to show (in my app’s template) only what came before the first parenthesis, like so:

Toyota
Ford
Honda
Kia or Chevy

Thanks to guide on how to use regex to remove everything after a particular character, and this refresher on how .replace() works, I had this problem solved in a matter of minutes with the following expression, where params[0] is the string (more about why my method looks like this after the code):

export function stripParensFromCarData(params/*, hash*/) {
  return params[0].replace(/\(.*\)/,'');
}

I used this method in an Ember helper I wrote to format strings for display in a handlebars template. The helper was hooked up like so in the .hbs file:

{{strip-parens-from-car-data carString}}

My favorite tool for testing regular expressions as I write them is regexr.com.

WordPress + MaxCDN + W3 Total Cache broken styles on main page fix

I recently hooked up one of my WordPress blogs to use MaxCDN (set up via the W3 Total Cache plugin) for serving stylesheets, images, and other things. Everything was going great except the main page of my blog was completely unstyled. Curiously enough, all of the other posts of my site had styling.

The console output in Chrome was a little help, showing me that the page was trying to find the .css and .js files at http://array/wp-content and http://array/wp-includes.

The “missing file” error stack looked like this:

GET http://array/wp-content/themes/blognametheme/style.css?ver=2.2.7 net::ERR_NAME_NOT_RESOLVED
GET http://array/wp-includes/css/dashicons.min.css?ver=4.4.2 net::ERR_NAME_NOT_RESOLVED
GET http://array/wp-content/plugins/jetpack/css/jetpack.css?ver=3.9.4 net::ERR_NAME_NOT_RESOLVED
GET http://array/wp-includes/js/jquery/jquery.js?ver=1.11.3 net::ERR_NAME_NOT_RESOLVED
GET http://array/wp-includes/js/jquery/jquery-migrate.min.js?ver=1.2.1 net::ERR_NAME_NOT_RESOLVED
GET http://array/wp-content/plugins/jetpack/modules/wpgroho.js?ver=4.4.2 net::ERR_NAME_NOT_RESOLVED

Basically, 20 minutes of Googling and reading about W3 and caching later, it dawned on me that the problem might be minification. I unchecked minification in W3 Total Cache and now it works.

w3_turn_off_minify

Moral of the story: if you get some weird styling or jquery issues on your WordPress blog, try unchecking minify in W3 Total Cache.

Where is the WordPress installation directory on Digital Ocean?

On Digital Ocean, assuming you did their fast install when you set up your droplet, the WordPress installation is located in /var/www

where_is_wordpress_installation_digital_ocean

This is also:

  • where your .htaccess file lives
  • where you upload your .html file for Google Analytics
  • where you’ll find the folder for uploading your theme (wp-content/themes/ThemeNameHere) – or where you can directly upload updates to its .php or .css files without having to re-zip the whole thing

Setting up MaxCDN with a WordPress blog hosted on Digital Ocean with a custom domain

This guide was written after I completed the process of hooking up MaxCDN to my Digital Ocean hosted WordPress blog.

maxcdn_logodigital_ocean_logowordpress-logo

This wasn’t a straightforward process, partially due to my own errors and partially because I was using WP Super Cache which I’m pretty sure just doesn’t cooperate with MaxCDN for reasons I may never understand. However, I now have it working so here’s my guide to everything I did.

Why I wanted a CDN: To speed up my top money-making property, which is also my slowest because it’s got long articles and lots of images.

I chose MaxCDN because it seemed to have a lot of good reviews and at about $10/month was reasonably priced.

Setting up MaxCDN with W3 Total Cache and a custom CNAME on Digital Ocean

I signed up and was disappointed to see that the URL MaxCDN gave me by default included the business name I used when I signed up. I wanted cdn.mysitename.com, but by default MaxCDN gave me cdn1.mybusinessname.netdna-cdn.com. MaxCDN calls this the “branded domain” and you can use it as-is, but I would guess most people want to customize it.

My business name and my website name are not the same and I didn’t want to expose the former in the latter. (They don’t tell you they’ll use your business name this way when you sign up, nor do they let you change it once you opened your account. Ugh.)

Fortunately, you can set up a custom domain and use that instead, and my steps below include that process.

Step 0: Set up a pull zone. MaxCDN has good documentation on pull zones.

Step 1: Enter your custom domain into the pull zone settings. Go to Pull Zones > Settings and fill in the Custom Domains field with cdn.yoursitehere.com (or cdn1.yoursitehere.com, or whatever you prefer. The important thing is that all three parts of the url are present.)

Step 2: Get into Digital Ocean’s record management. Inside Digital Ocean’s droplet management page, go to Networking and then go to Domains. Click the magnifying glass next to the domain you’re adding this CDN to to get into its records. More help adding/editing domain records in Digital Ocean.

digital_ocean_access_domain_records
Look in Networking, Domains

Step 3: Add a CNAME record to your droplet’s domain.  If you want cdn1.yourdomain.com, fill the form out like this:

  • Enter Name: cdn1
  • Enter hostname: cdn1.yourdomain.netdna-cdn.com (the “branded” domain that Digital Ocean gave you by default)

Be sure to click the Create CNAME Record button to actually add it to the list of records.

digital_ocean_cname_for_maxcdn

Step 4: Wait about 20 minutes for it to propagate. 

You can watch it propagate here: https://www.whatsmydns.net/#CNAME/cdn1.yourdomaincom

Assuming nothing else is conflicting (you didn’t leave your DNS hooked up to CloudFlare like I did, you don’t have a competing www.yourdomain.com record like I did, etc), this should happen in 20 minutes or less.

Step 5: Now you can hook it up in your WordPress caching plugin! MaxCDN has docs for setting up MaxCDN with many different WordPress caching plugins here.

At first, I was using WP Super Cache and every time I turned on the CDN feature my site’s styling and images disappeared. I fought with this for a while, got good and frustrated, then tried W3 Total Cache like MaxCDN suggests and WOW – it was like night and day. I followed MaxCDN’s tutorial and basically, it just worked. Be sure to whitelist your site’s IP (go into Terminal or command prompt and ping www.yoursite.com to get your site’s IP if you don’t know it, or look in Digital Ocean’s droplet list).

If you’re having a problem with WP Super Cache making your styles and images disappear with MaxCDN, try W3 Total Cache instead.

Step 6: Verify it works by loading your site

If everything’s working, you should be able to load your site (yoursite.com) at its usual url (not the cdn url) and look in the network tab of your browser to see responses coming in from the CDN url (cdn.yoursite.com).

Fast way to check: right click any image on your site and view it in another tab. Its url should be your cdn’s url.

If you don’t have any images, you can see this in Chrome by right clicking to Inspect and then click over to the Network tab before loading your site. Hover over some resources (like .css resource) and you should see cdn1.yourdomain.com.

You should also start to see improvements to your page’s load time immediately.

If you don’t see the changes right away: While the cdn1.mysite.com changeover was observable right away on the computer I was working on, it wasn’t on my laptop. The cause seems to be the computer’s own DNS settings. By switching my laptop’s DNS settings to Google’s, I was able to see the most up-to-date (ie: not cached) version of the website.

How to use Google’s public DNS on your Mac or Windows machine: https://developers.google.com/speed/public-dns/docs/using

(Alternatively, waiting a while – up to a day – should resolve it with no changes to your computer.)

Pingdom results, before and after MaxCDN

Here’s a couple of “before” load times on my website, taken less than a minute apart and both from New York City. The thing I often notice on Pingdom’s Website Speed Test is how much variance there can be in load time across multiple tests when all other factors remain the same (location testing from, time of day, etc).

Site speed: before

Here, there’s a huge difference in load time just on these two “before” tests.

pingdom_ny_test1

pingdom_ny_test2

The kind of extreme difference in load time seen above is why I like to run several Pingdom tests when collecting my “before” data before making a change that I think should effect load time. Here’s another test, this one from San Jose, California.

pingdom_san_jose

Site speed: after

Whoo! Look at that, down to <2 seconds since turning on MaxCDN:

pingdom_ny_after_1

Here’s an even faster one, best one I saw in my several tests:

pingdom_ny_after_2

And one from San Jose:

pingdom_california_after_1

So far I like MaxCDN. Their online support is very responsive. I sent a detailed plea for help on a Sunday afternoon in the U.S. and had a (reasonably) customized response within an hour. Their documentation is plentiful and thorough. They include many examples and their screenshots are up-to-date with their current interface.

The real test will be in seeing if getting the site speed down to ~2 seconds has any noticeable effect on the site’s Google rank and total conversions (sales).

CDN Traffic Boost?

Totally unscientific study here, but my site’s traffic pulled out of a slump as soon as my CDN hookup went live. (March 17 is just beginning as I post this update.)

maxcdn_stats_effect

Relevant MaxCDN docs and tools:

Ember 2: Calling an action from a checkbox in Ember 2.0 three different ways

I recently implemented a checkbox in an Ember 2.0 project that, when checked/unchecked, would call an action and change some properties.

Searching the web reveals many different approaches to this problem, some of which (depending on your project’s needs and stack) may be more suitable for you than others.

The first time I needed a checkbox to call an action in Ember, I was just building a quick ‘n dirty prototype and I wanted to keep things simple and skip observers, components, etc., which I was able to do with some basic HTML and an Ember controller.

Simple Ember checkbox HTML/JS solution

Here’s the simplest implementation of an Ember checkbox calling an action I can come up with. It’s just HTML and JavaScript.

See it working in this JSFiddle

HTML:

<input type="checkbox" 
 id="checkbox-toggle" 
 name="toggleCheckbox" 
 checked=toggleChecked 
 {{action "toggleCheckBox" on="change"}} 
 />

JS:

setupController: function() {
 this.controller.set('toggleChecked', true);
 },
actions: {
 toggleCheckBox: function() {
 this.controller.set('toggleChecked', !this.controller.get('toggleChecked'));
 }
}

Ember checkbox as a component

Ember offers an {{input }} component that you can now hook up to actions (that apparently wasn’t true in earlier versions of Ember, but it’s true as of this writing which uses Ember 2.0).

The input component implementation looks like this:

{{input type="checkbox"
      id="checkbox-policy"
      name="checkboxPolicy"
      checked=readPolicyChecked
      change=(action togglePolicyRead)}}

To register the action with the controller, you’ll need to add this to the corresponding .js file.

// Set a method on the controller which will send the action
this.controller.set('togglePolicyRead', function() {
  this.send('togglePolicyRead');
});

If you don’t set this method on the controller, you’ll get a console error like:

Uncaught Error: An action could not be made for `togglePolicyRead` in (generated page.policy-review controller). Please confirm that you are using either a quoted action name (i.e. `(action 'togglePolicyRead')`) or a function available in (generated page.policy-review controller).

As an aside, using Ember’s input component to generate the checkbox will just render into normal HTML (like you see in my first example) and you can confirm that by viewing the page source on your project.

Ember checkbox as HTML with handlebars for the checked property

What if you can’t use the {{input}} component because of a conflict with handlebars syntax? Maybe you’re working inside a component, or there’s some project-specific reason you need to go this route. Here’s an approach you can try that uses HTML for the input and wraps the checked={{property}} in handlebars.

<input type="checkbox"
       id="checkbox-green"
       name="greenCheckbox"
       checked={{greenChecked}}
       {{action "toggleGreen" on="change"}}/>

With this technique, you also don’t have to set up the action on the controller like I showed in the previous technique.

The Ember project I worked on serves its templates as .jsp files and this approach was the popular because we could skip the cumbersome “send” step on the controller. Now, whether that’s “the Ember Way”, I’m too new to Ember to say, but this got the job done.

Blogging for bucks: Year 2 report – growing to greatness

This report is for Year 2 of my “blogging for bucks” endeavor in which I turn my love of research and writing into a profitable hobby. Read about the first year here (it’s a much longer and more detailed post than this one and covers all the “how to get started” stuff).

When I started blogging for affiliate bucks in summer 2013 I said all of the following:

  • “I’m starting too late”
  • “All the good ideas are taken”
  • “The Internet doesn’t need another blogger”
  • “The people who actually make money off this know tricks and secrets I’ll never know”
  • “I’m going to shill products I don’t give a shit about, and it’s going to be boring writing about them.”

Then I went ahead and did it anyway.

Turns out, none of the above was true. 2015 was an excellent year, bringing in more than twice 2014’s haul.

pile-of-candy

I made $12,600 this year from the Amazon Affiliate program and Google Adsense. Just like in 2014 (my first full year blogging), nearly half of that money was made in the last three months of the year (I love you, holiday shopping season). It wasn’t all for me, though: the IRS took about a quarter of it as their cut in tax season (ow).

2015 Amazon Earnings screenshot
(my earnings are the bottom right number)

2015_amazon_affiliate_earnings

I still firmly believe that this is a viable make-money-online strategy that anyone with the willingness to learn, research, and write can do. It’s not too late to start. It’s not even very labor intensive, as evidenced by this “coasting year” still making a decent profit. Most of the work you’ll do is upfront when you set up a new site and load it with your (well-written) content.

To be frank, I ran out of blogging steam for most of 2015. I didn’t write but a handful of articles and I didn’t start any new blogs until December. I was busy with my brand new job and some major life changes.

But if 2014 was the year of sowing, then 2015 was the year of reaping. As the blogs aged, more people found them – and they liked what they found.

2015 Blogging Year in Review

January 

I started my first full-time programming job in January 2015. This was a career change many years in the making and I didn’t have any spare brain cells for my blogs after work each day.

The sites coasted through January – I added no new content and I didn’t promote anything.

But sales didn’t drop with the conclusion of the US holiday season, curiously enough: January 2015 brought in almost as much ($739) as December 1014 ($819). My guess: people go buy themselves the stuff they didn’t find under the tree.

February and March

Sales dropped these months, reaching their lowest point of the year in March ($386). The holiday gravy train had to end somewhere, but I don’t think this was some flaw in my blogs – I think people just don’t buy that much in these months, or they don’t buy that much stuff in the niches my sites are in. Traffic more or less held steady, though, across all sites.

April, May, June, July, August, September

In April sales began to climb again, peaking in August with $1,166! I continued my do-nothing approach and added very little new content during these 6 months (I added 1-2 articles to each of my top-performing niche sites). I put some minimal effort into updating existing content to keep it fresh, though. On Gizmo Blog, this meant keeping up with manufacturer updates to products and industry news.

I think the moral of the story here is to not “give up” on a site. Leave it up, sites are cheap. Even my worst performing sites making $1-2 a month pays for their own domain by the end of the year, and all the while they’re aging like a fine wine (in Google’s eyes).

It’s okay to keep adding content at a snail’s pace, updating here and there, tweaking things along the way. Maybe if you want to make five or six digit earnings every month then you need to add content weekly or daily or whatever, but I definitely didn’t add anything meaningful to my already-established blogs and I was rewarded with a decent “side income” for my complete lack of effort.

October, November, December

Here they are: the three months that make 48% of the year’s income. November was the top-performing month, bringing in $2,076, but December was almost as good, bringing in just $30 less than November.

In honor of the shopping season, I did a few things to help buyers find me:

  • Added a 2015 holiday buyer’s guide and top sellers list for each niche site
  • Tweeted those lists (regularly) from each site’s associated Twitter account

Honestly, I’m amazed that a collection of neglected sites did so well. Imagine what they could’ve done if I’d been adding content all year long!

Year in summary (a pie chart!)

As the chart illustrates, Gizmo Blog accounts for a full 66% of my Amazon Affiliate earnings, and Craft Blog the next 20%. That means a full 86% of my earnings come from just two sites. Better diversifying my Amazon Affiliate income is one of my goals for 2016 – I don’t like having too many eggs in any one blog basket.

2015_amazon_affiliate_pie_chart

“Other” includes this blog, TILCode, which made a grand total of $7 off Amazon Affiliate earnings in 2015 :D (Thank you, whoever bought a book or two through this site.)

What about SEO techniques?!

I chatted with a number of people about blogging for side income in 2015 and the most common question they asked me was, “what kind of SEO do you do?”

The short answer is, I don’t do any.

I pick a product, research it (sometimes I buy it and use it myself), basically obsess over it, and tell people why it’s better than its competitors in a 1500-2500 word review.

I pick products I like myself – stuff I’d buy if I had unlimited funds, or stuff I already own. That’s it! People who want to know this information – people on the cusp of making a purchase – find me through Google and go through my site to Amazon to make their purchase, which I then get a cut of at no extra cost to the shopper.

There are a lot of techniques out there that promises results (paid links, WordPress plugins, content strategies, backlink strategies) and I can’t vouch for any of them. I mean, maybe there’s something out there that would turn my $2,000 months into $5,000 months, but at what cost? Hundreds of dollars in bought backlinks that Google would eventually sniff out and knock me down in the search results for? I’ve been content to build my sites myself and let the natural links come in at their own pace. YMMV.

2016 goals

  • Better diversification – 86% my Amazon Affiliate income comes from just two of my sites, so I want to get that down to 50% by EOY by growing income from other sites.
  • Alternative revenue source – virtually all of my passive online income comes from Amazon Affiliate program. It’s a great program but if it ever goes away, I’ll be pretty sad and won’t have anything to back it up.
  • $18k in earnings – that’d be nice!
  • Set up my blogs as a legal business entity, as per my financial adviser’s advice and because it’ll make tax season easier and more in line with what the IRS expects from a “side business”
  • Optimize sites – load times are bad (>6 seconds in some cases), they’re mostly on shared hosts, I get a lot of “Error Establishing Database Connection” problems (my VPS seems to get overloaded with one site in particular) – there’s just a lot of technical performance things that could be better
  • Actually add more new content to sites

And that’s it for 2015! Onwards to 2016, where I hope to do a better job of adding content and optimizing the sites for even better earnings.

Code School Review: The Magical Marvels of MongoDB gets you started with shell syntax

Code School’s got a new database path! Woohoo!

I was invited by Code School (and comped with a free month subscription) to try out The Magical Marvels of MongoDB. I’m not that experienced with backend data stuff, so I was excited to fill in a bit of my knowledge gap with this intro-level course.

code_school_banner

About Code School

As some readers already know, I’m a big fan of CodeSchool.com. Code School is great for both curious newbies (“is coding something I want to do with my life?!”) and for more experienced programmers who want to get a feel for a new technology without going through the hassle of setting up an environment, a new project, and then wading through a pile of documentation.

They’ve grown a lot in just the last year, so check ’em out! Especially if it’s been a while since you last visited.

About the MongoDB course

What you need: a modern web browser – and that’s it. I used Google Chrome and experienced no technical difficulties. All the videos and interactive lessons take place in-browser.

Time spent from start to finish: about 4 hours. The course is divided into 5 sections, with about 10 minutes of video instruction per section.

Topics covered: inserting and finding database documents, transforming record data, filtering documents by various search criteria, embedding vs. referencing, and aggregation.

Overall instruction quality: Excellent. The class’s instructor, Joel Taylor, speaks clearly and concisely. On-screen text is clear and readable, and the graphic design is pleasing and modern.

mongodb_which_route

Wins

The course is largely a tour through the syntax used in MongoDB’s shell. The course does a great job of showing the student how MongoDB structures its data and how to perform simple operations like adding, removing, and updating parts of database objects as well as filtering results by more sophisticated criteria.

The error checking is pretty good – it caught most of my bonehead mistakes and the hints were relative to the mistakes made. Occasionally, I ran into a problem where the error checking couldn’t tell me what I had done wrong, such as omitting the “$” before “$lte” in one case, but I never stayed stuck for long.

codeschool_mongodb_editor

I liked how the course never gave me ready-made code to work from. I have a vague memory of an earlier Code School course giving me existing code to add to, and I feel like I got a lot more value out of the repetition of typing the same “boilerplate” (ie: db.wands.find() ) each time I started another section.

The pacing was good: I especially enjoyed the multiple-choice format to section 4, which I felt deepened my understanding of embedding vs. referencing and also was a nice change of scenery from the usual coding challenges. Lessons never dragged on too long, so I could squeeze them in between other things I had going on.

I love the in-lesson shortcuts to the relevant video sections, the reviewable slides, and the suggestion near the end of Lesson 2 to look in Mongo’s own documentation for help with $mul. Since I usually work with documentation up on my second monitor, I appreciate the validation. :P

Shortcomings

As with many CodeSchool courses, the larger context is probably the thing I miss the most in this course. I loved the intro at the beginning: the conceptual rundown (“NoSQL”, collections, the diagrams), but I didn’t get a great feel for the whys of MongoDB. Why would a project be better served by MongoDB over MySQL? What are the advantages of MongoDB and tradeoffs?

The course is a great way to try out the technology, but for me, finding the syntax of a language or technology is usually the simplest step (thanks to documentation). My personal learning curve tends to steepen as a result of the quirks, the gotchas, and the… mindset (for lack of a better word) of a technology.

And, of course, the usual caveat applies: practicing a language or technology in the browser is a lot like reading foreign language words out of a book vs. attempting a conversation with a native speaker. If you were to actually make a project using MongoDB, you’d find there’s quite a bit of setup, interfacing with the rest of your project, and debugging to get through first. CodeSchool doesn’t cover this aspect of the experience, but it’s a pretty big part of using any new technology.

But hey, these aren’t really problems with the course, just things that an intro-level online class can’t be expected to deliver on in the first place. The fact that I’m missing them is probably a testament to Code School’s ability to get me interested enough in the technology to want to know more.

The bottom line?

Great course! I finished it and wanted more. My favorite parts were the sections that went beyond syntax and into best practices, like the embedding vs. referencing parts. Don’t expect to be able to speak fluently about MongoDB after just this one class, it’s too small in scope for that.

But I’m wishing there was more, so – good work, Code School!

mongodb_codeschool_course_complete

7 IntelliJ IDEA tips and settings you’ll probably love

Hardly a week goes by where I don’t learn something new about IntelliJ! Here are just a few of my favorite IntelliJ settings tweaks and workflow tips.

This article was written for IntelliJ IDEA 14 professional and community editions.

1. Exclude some folders from search

If searching in your project is returning a lot of non-project files you’d rather not see (such as files in /node_modules, /tmp, or /build), you can permanently exclude those files.

Go to File > Project Structure > Project Settings > Modules. Right click any folders you don’t want to ever search in and mark them as Excluded. Done!

exclude_folders_from_search_intellij_idea

2. Highlight current file in project hierarchy

Do you want to see where your currently active file is in the project structure? Of course you do. Turn on “Autoscroll from Source” by clicking the little gear in the little toolbar at the top of the project structure window.

Now whatever file you’re editing will be automatically highlighted in the project structure pane.

highlight_file_in_hierarchy

3. Start a local server with a single click

For all your little web projects that you want to test in browser without bothering to set up a server first, just right click the file you want to serve and choose Open in Browser.

local_server_intellij_right_click_file

I overlooked this feature in the past because I thought it was just going to open the file all vanilla and stuff, but it totally starts a little standalone server! 

intellij_temp_server

4. Resolve git conflicts

IntelliJ IDEA’s git merge conflict resolution tool is fun and convenient. Just right click in any of your project’s files (doesn’t have to be the one with the conflict in it) and go to Git > Resolve Conflicts…

right_click_resolve_git_merge

You’ll get a modal with a list of all the files containing conflicts. Choose Merge…

files_with_conflicts_git_merge_intellij

In this screen, you can compare your changes (on the left) to what you got from the server when you pulled (on the right) and view the result (in the middle). Move changes to the result by clicking on the >> and << symbols, and reject changes by clicking the X. You can even edit the final version manually right there in the middle pane.

intellij_merge_conflict_tool

5. Search EVERYWHERE

You know you’ve seen it… somewhere. But your project is huge and that file could be anywhere. Double-tap the Shift key to open up Search everywhere. I use this shortcut to hop between files all the time because it’s just so convenient.

6. GitHub integration

In the right click menu (click inside a file or on a file in the project hierarchy) there are a couple shortcuts to GitHub. Open on GitHub is handy for jumping right to the file you’re working on to view its history, Create Gist is handy if you like making Gists.

create_gist_from_intelliJ

7. Turn on Annotations to know who to blame (it was probably you)

Who wrote this line of code? Now you can know: right click in the left margin (where the line numbers are) and turn on Annotate.

annotate_intellij

Hovering your cursor over individual lines reveals the last commit message, too.

git_annotate_names

There you have it: a short ‘n sweet guide to 7 helpful IntelliJ tools, shortcuts, and settings.

Code Fellows Post-Accelerator Update (4 months into first job)

It’s been…

  • Several years since I first dreamed of writing script or code for a living
  • 1 year since I left my unhappy video game designer job
  • 6 months since I graduated from the Code Fellows Full Stack JavaScript Dev Accelerator
  • 4 months since I started my full-time programmer job

What a trip! Thanks to Code Fellows in Seattle, I am super happy to report that I am now a full-time programmer and loving my new job!

seinfelddance

I had tinkered with coding for years in my free time, but never in a substantial enough capacity to turn it into a full time job on my own. Code Fellows was that missing piece, and this is my post-Accelerator update!

My review of the Seattle-based Dev Accelerator can be found here, if you’re curious about the 8 week program itself.

Yes, I got a job after Code Fellows!

code_fellows
@CodeFellowsOrg is now in Chicago and Portland!

And it’s a great job! Like, an unbelievably great job where they pay me to solve interesting Angular and JavaScript problems! My title is Associate Software Development Engineer and I work at Expedia in Bellevue, WA.

So, yes, to all those wondering (and emailing me!), Code Fellows will work you hard, but it is sufficient training for an entry-level programming job (provided you do your part), and the skills you learn in the class will be useful in your job, even if your job is in a different language or technology stack.

Job search rocket fuel: The mid-accelerator resume blast

Code Fellows definitely made good on their promise to put student resumes in front of local employers. Halfway through the Accelerator (4 weeks in), Code Fellows collected and reviewed resumes from every student and fired them off to 40+ Seattle and Eastside employers. Holy wow – they knew about companies I’d have never found on my own.

The “blanket the city” approach worked, but I had a few small gripes that I think other students should be aware of.

  1. The resume blast went to companies I wasn’t interested in (…yet). I gave preference to companies closer to me on the Eastside (so I wouldn’t have to relocate), but my resume went to plenty of companies in downtown Seattle. I felt bad turning down these companies (burning bridges! ahh!), especially since I knew I would become more interested in relocation if my job search started to drag on.
  2. I prefer to customize my resume and cover letter to each position, emphasizing different aspects of my experiences for different positions.
  3. The blast went out too early. My final Accelerator project, my post-Accelerator project, and my portfolio website were not on that early version of my resume. Employers I talked to over the next couple months didn’t know about these things, and those projects and my portfolio site were the strongest showcases of my work.

Basically, I didn’t have iron-clad control over my job search in the first few weeks. And I like iron-clad control over my job searches.

I had only a vague sense of which companies I had already “applied” to and I inadvertently wasted the time of employers I probably wouldn’t have applied to on my own (because they were too far away or didn’t have the kind of workplace culture or benefits I was looking for).

But if that’s my biggest gripe, then I don’t have much to complain about. Code Fellows did a good job supporting its grads, and a quick glance at my fellow classmates’ LinkedIn profiles suggests more than half have already found full time gigs.

Really, I didn’t have to look hard for interesting job opportunities after graduating, and I still don’t – Code Fellows continues to send job leads to alumni, and my LinkedIn profile gets so much email I’m kind of afraid to look in that inbox.

The First Calls

The first couple weeks after my September 26th graduation were really quiet (which was good, I don’t think too many people want to go straight from the Accelerator to a full time job) and then I started getting calls and emails from employers in late October and early November.

Most of these came from “resume blast” employers, but I also ended up in the hands of some recruiters trying to fill really short project positions (like, 3-week or 2-month contract projects). I thought these projects sounded exciting but all of these opportunities fell through for some reason or another.

A big question near the end of the Accelerator that many students asked was whether recruiters were worthwhile. I’ve personally never had a productive relationship with a recruiter in nearly ten years in tech, but someone must be getting value out of recruiters since they’re still in business.

For whatever it’s worth, the three companies I ultimately interviewed with contacted me directly, either via their technical director or their own hiring department, with no recruitment firm involved.

Technical Interviews

By mid November I had phone interviews scheduled with three companies. Two of them had my info from Code Fellows, and one of them I had applied to on my own. Of those three companies I interviewed with, two chose to conduct the technical interview over the phone.

The first company had a setup where I shared a screen with my interviewer and coded in real-time as my interviewer watched and talked to me over the phone.

The second company conducted the technical interview as a series of questions, sans-computer, although my interviewer had poked through my Github repos and had some questions for me about code I had posted to Github.

The third company (where I now work!) brought me in for a one-hour in-person technical interview, which I really enjoyed and preferred over the phone interviews. This technical interview had the most in common with Code Fellows’s style of interview training, where the interviewer asked me questions and I wrote code on the whiteboard and answered questions as we went along.

In all three technical interviews with three different companies, I felt that my Code Fellows training and in-class interview practice had sufficiently prepared me for the questions I was asked. I was asked questions I didn’t know the answer to in all three interviews, but it wasn’t the end of the world. I just said I didn’t know, said what I would do to find out, then said that I would love to know, and in all cases, my interviewer explained whatever it was to me. (Yay, I learned something new!)

Technical Interviews: Questions I was asked

In no particular order, here are the kinds of questions I remember being asked:

  • Write a function that determines if a string is a palindrome
  • What does REST mean? Why is it important?
  • Write a function that returns just the odd numbers from an array I pass into it
  • Now modify that function to return every other odd number
  • Describe dependency injection in Angular
  • Tell me what kinds of tests you would write for that (whatever that was)

Keeping up after the Accelerator

I filled my post-Accelerator free time building a brand new AngularJS app of my own, a sort of “capstone project” that summarized my knowledge thus far. This project kept my skills fresh and I would recommend other Code Fellows grads do the same (after graduation, of course) to really solidify their understanding of the concepts likely to come up in interviews.

cbm_app_screenshot_11_12_2014
My post grad project: a recipe site with a back-end interface for adding and editing recipes. I rolled my own CSS and it even has automated tests!

I brought this project with me to my interview on a laptop so I could show it to my interviewer, and that seemed to go over very well. (I got the job, after all!)

Other things I did to stay sharp after the Accelerator:

  • Codewars “kata” – some of these were really hard but they’re also one of the only training things I’ve found that includes testing
  • Updated my WordPress blogs’ themes and added customization I always wanted but never really understood how to do before (this stuff was easy after the Accelerator)
  • Built my coding resume / portfolio site from scratch
  • Aimed for a minimum of 1 meaningful Github push per day on whatever project of my choosing (I find streaks and those little green cubes very motivational)
  • Read up on concepts I learned about in the Accelerator but wanted to understand better, like Big O, asynchronous Javascript, data structures

My first month on the job

Like many grads, my primary fear going into my first programming job was that I wasn’t sufficiently qualified. I still felt pretty green, despite all my experience. (Some people tell me this feeling of being inept despite accomplishments that prove otherwise may never fully go away, and recognizing that definitely helped.)

My first week on the job was spent learning the code base, the project structure, learning the workflow (how to run tests, how to get a build running), and setting up my work laptop.

There was so much to learn, and this project is so much more complex than anything I’d coded in before. (This is why I think building real, standalone apps / programs is best for learning to code once you’re past the online tutorial basics.)

project_structure
My work project is more complex than anything I ever built on my own.

Fortunately, everyone was happy to help and answer questions, and I quickly found several more Code Fellows alumni at the company who started before me or on the same day as me. We met up at a local Starbucks early on to share experiences, which was reassuring for everyone involved.

In that first month, my main contribution was adding a button that exposed a back-end feature the rest of the team had been working on for some time. I wrote the logic that determined when that button would be clickable, and added unit and end to end tests to help spot any future regressions.

I also had the opportunity to debug existing Ruby/Cucumber tests, learn a little bit of Scala, and write a few MySQL queries to look at how data was saved in the database. In that first month, I found that the biggest challenge wasn’t writing new code, it was understanding existing code and the complexities of the project’s structure.

The next 3 months

Around weeks 5-6 I started to feel like a more full-fledged, contributing member of the team. The vast majority of my work is in modifying existing code to perform a new function or to fix an unwanted behavior.

Here are just a few of the things I worked on in that time:

  • Small optimizations to Cucumber test suite aimed at reducing the test code’s reliance on fragile XPaths and removing sleep() and wait() calls
  • Improvements to the way dates are handled in the app, including adding the much-beloved moment.js library to the project
  • Collaborating with another programmer to develop a date range “collision” algorithm that can check if a variety of date ranges overlap correctly (or incorrectly) according to a complex set of business rules
  • Upgrade project’s Angular version and assist in the migration
  • I had the opportunity to attend a day-long Test Driven Development workshop and bring those practices back to my daily work

My team’s leaders are big fans of pair programming (to the extent that we have dedicated 1pm-4pm “core pairing hours” every day), so a lot of the work I do is in the company of at least one other engineer. I’ve learned so many good techniques and habits from working with my teammates, and I can’t overstate how great this has been for my own development and quick integration with the team.

(I hope it’s apparent from my writing here how very happy I am to be working on this project with this team – I love it, it’s better than I ever dared to hope.)

Happy Ending / New Beginning

So that’s it! I can’t believe it’s been six months already. The Code Fellows Accelerator changed my life: my new role is challenging, and working at Expedia with my team has kept me just as inspired and excited as I was when I embarked on this journey a year ago.

yay-gif-dance

Using tags to run select Cucumber tests

Today I learned… that I can “tag” select Cucumber scenarios and run just the tagged ones, speeding up my testing and making it faster to debug a failing test.

I’m working with Ruby Cucumber tests for my current project and as the tests grew in number and complexity, I found myself wanting a way to run just a specific test.

If your tests are set up anything like mine, you can just add a tag with an @ symbol to your tests like so:

@javascript @tagname
Scenario: Verify that the thing in the thing works
Given I am already logged in
And the page has finished loading
Then the thing should be in the thing

When you run your Cucumber tests from the command line, just add –tag @tagname as an argument:

cucumber --tag @tagname test/specs/features/testfile.feature

This is just a simple implementation that might be useful if you are trying to debug a single test. Taken to its logical conclusion, you could have entire suites organized under different tags for different purposes, environments, etc.

More Reading

Most of what I know about Cucumber tagging came from krazyrobot.com’s excellent guide on Cucumber tagging.

cukes