Node.js Quickstart Guide, Now With 50% More Pro Tips

Those of us who just graduated from the Flatiron School have plenty of experience setting up Rails applications. Maybe we’ll choose Sinatra if we’re feeling daring and minimal. But the internet is a big place, and there are tons of other frameworks to explore. One of the most popular (and trendy) choices today is Node, running on the Express framework.

To be fair, I built my final project for the Flatiron School in Node. But I concentrated on the database work and general functionality, allowing one of my teammates to set up the server and routes. I decided to review Node by setting up a simple “Hello World” application with help from Aaron from Fog Creek/Trello. Trello actually runs on Node and Express so Aaron had some great tips for me!

The Node/Express documentation is very good. Once you install both technologies and make a directory for your app, you just have to make the two required files: package.json and app.js. The former keeps track of all your dependencies and behaves virtually identically to a Gemfile in Ruby. The latter sets up routes and actually starts the app. In any real-world scenario, you’d also need files for views, app logic, styling, etc. But for the purposes of our Hello World app, you can get away with the two files.

Here’s what your package.json should look like at first:

image

Now you can just type:

npm install

on the command line to install the one listed dependency.

Pro tip: If you want to add dependencies (like templating engines or anything else) in the future but don’t feel like manually adding it to package.json, just install it on the command line with the --save option. For example, npm install underscore --save.

Now we have to actually set up the server. The documentation for what goes in the app.js file is quite clear:

image

If you’ve followed these steps exactly you should have about 8 lines of code in app.js. Now you should just be able to type:

node app.js

to start the server. Go to localhost:3000/hello.txt in your browser and you should see “Hello World”!

You can define any route you’d like here by changing the arguments passed to app.get(). (You can also define POST endpoints with app.post().) The sample code sends a string response but you could easily pass in a view here as well.

Pro tip: You can define a middleware function here that will get called every time the server receives a request. For example, checking the request for certain media types to redirect users if they visit your site on an iPad. Just pass a function to app.use().

Congratulations! You’ve officially set up a basic Node app that knows how to handle routes and display text passed in as strings! The rest of this guide will focus on setting up apps with more complicated functionality. Remember that every time you make a change to your code, you must restart the server on the command line if you want to see the changes reflected in your browser.

OPTIONAL: Getting Started with a Templating Library (Consolidate.js)

Pro tip: At this point you might want to make a .gitignore file and add node_modules to it. Everybody developing on the codebase needs to npm install dependencies on their machines anyway, so there’s no reason to check in these potentially huge files.

If you’re using this guide to set up an app with multiple views, you might want to consider using a templating library. Consolidate.js is a great tool that plugs into Express and allows you to select almost any templating utility. I arbitrarily chose to use Consolidate to set up Underscore templating, so my code samples will use that syntax. Make sure to:

npm install consolidate --save

if you’re following along. You also have to require consolidate at the top of app.js:

var cons = require('consolidate');

Once this is done, here’s some sample code to get started using underscore with consolidate:

image

The templating library is now expecting all of your views to live in a views directory, so make this folder.

The sample route we’ve defined is the index, so now create an index.html in your views directory. To make sure you’ve set up underscore templating correctly, let’s evaluate the variable it gave us. Type this in your index.html:

<%- title %> 

Now if you start the server with node app.js, you should be able to go to localhost:3000 and see this:

image

Hooray! Underscore has interpolated the title variable! Of course usually you’d pass in a model here instead of cluttering up your app.js file with random variables.

OPTIONAL: Getting Started with Nodemon

At this point you’re probably tired of restarting your server EVERY time you make a change in your code. Luckily, there’s a better way. Nodemon will watch for changes in your source code and and automatically restart the server for you, enabling lazy/efficient developers everywhere. It’s similar to Shotgun in Ruby projects. Just run:

npm install -g nodemon

to install it globally. This means you can use it on future projects as well. Now you can just run:

nodemon app.js

once instead of

node app.js

many times. Note that you’ll still have to refresh your browser to see changes, but your server will handle reloading for you. You won’t see nodemon listed as a dependency for this project since you’ve installed it globally.

Pro tip: In case you’ve lost track of our file structure, here’s a screenshot of what it should look like at this point:

image

And there you have it, folks! You’re now well on your way to setting up an interesting, complicated Node.js project using the Express framework. The documentation is pretty good but the error messages are AWFUL (think something like “generalized error”!) so if you have any problems, feel free to message me at ilana.sufrin@flatironschool.com.

A Rails Grammar Lesson

Since I first started learning Rails, one thing that struck me was how incredibly smart the framework is. Not just in anticipating paths and RESTful patterns, but also how class Person magically becomes table People in the database. How in the world does Rails know that it’s not the Persons controller/table? Has somebody hardcoded every possible grammar edge case? I made it my mission to find out.

As this handy blog post points out, if you want to see how Rails would pluralize a word, just run a generator command with the --pretend or -p option:

image

This prints out a list of all the files Rails would create if you ran a generator command without the option. This is also useful if you forget the difference between scaffolds and resources.

Convention is part of what makes Rails so powerful. The framework can anticipate what you need and generate your file structure for you– but at the end of the day, rules were meant to be broken. You can turn off pluralization completely by adding this line of code to your config/environment.rb file:

ActiveRecord::Base.pluralize_table_names = false

But keep in mind that your whole project will break.

You can also experiment with existing conventions by testing pluralization patterns in your Rails console. Use the pluralize and singularize methods:

image

Where do these methods come from? Glad you asked! Rails depends on a gem called ActiveSupport that provides string pluralization patterns (and MANY other things.) Many of the files in the “inflector” directory deal specifically with how and when to pluralize words.

If you love reading source code, the inflector/methods.rb and string/inflections.rb files use higher-level methods like tableize, which depends on the lower-level methods like plural and singular in the inflector/inflections.rb file. The rules are defined in the first place in the lowest-level file, active_support/inflections.rb. It handles both normal and irregular patterns.

image

The Ruby on Rails Cookbook explains how to override the rules provided in the inflector files:

_`$ ruby script/console
>> "foo".pluralize
=> "foos"`

Rails calls words that are the same in both plural and singular form uncountable. To add the word foo to a list of all uncountable words, add the following to the bottom of environment.rb:

config/environment.rb:

`...
Inflector.inflections do |inflect|
 inflect.uncountable "foo"
end`

Reload script/console, pluralize foo again, and you'll find that your new inflection rule has been correctly applied.

`$ ruby script/console
>> "foo".pluralize
=> "foo"`

Other inflection rules can be added to the block passed to Inflector.inflections. Here are a few examples:

`Inflector.inflections do |inflect|
 inflect.plural /^(ox)$/i, '\1\2en'
 inflect.singular /^(ox)en/i, '\1'
 inflect.irregular 'octopus', 'octopi'
 inflect.uncountable "equipment"
end`

These rules are applied before the rules defined in inflections.rb. _
_Because of this, you can override existing rules defined by the framework._

So there you have it, fellow grammar enthusiasts. The Rubyists who came before us took the time to painstakingly define pluralization rules in this file. You can override them if you’d like. In fact, you might have to override them if your models are made-up or non-English words.

image

Baby’s First Hackathon

Over the weekend, I competed in my very first hackathon. It was run by IDEO, and the theme was waste and surplus in NYC:

http://www.ideo.com/hackathon/nyc/

I just want to reflect on my experience here since the hackathon was very different than I was expecting.

My friend Wenting is a UX designer at Viacom and my friend Jesse is a professional Rails developer, so they’re both way more experienced than me. We agreed that I would “help” Jesse but he would do the heavy lifting of architecting the backend. Wenting had already thought of an idea and briefed us on it before we arrived at IDEO.

When we got to the venue near Canal Street, we were surprised to discover that almost nobody was a developer, and almost nobody had a ready-made team. Furthermore, the hackathon was scheduled to be very short: it was only Friday and Saturday as opposed to lasting the entire weekend. I have a feeling that IDEO didn’t really know how to run a hackathon.

Most people got to work finding a team, but since I came with my friends we could get to work right away. We ended up picking up a fourth teammate, Hao, who is an amazing biv/dev guy and probably is the reason we were so successful.

Hao did market research on our competitors while we started programming. Wenting sat apart from us and built the frontend while Jesse and I brainstormed what our models and migrations should look like. The lack of communication turned out to be a huge problem later because Wenting built a single-page app that couldn’t be connected to our multi-page backend. We coded late into the night, went home for a few hours, and came back to IDEO at 9am the next morning.


On Saturday, Wenting arrived and told us that she had decided not to do photoshop mockups because there wasn’t time. She was just going to build what she saw in her head. I was a little nervous but agreed that we didn’t have time to build the app the usual way.

I was inordinately proud of myself a couple hours later when Jesse told me that form_for confused him so he always hard-coded the html in his forms. I insisted that we use form_for, and together we figured it out. Win for Flatiron!


Jesse and I inevitably ran out of time, so our app was barely functional. It was time to upload our slides, but we had almost nothing working. It could only do three things: authenticate with Google, calculate who’s closest to you (the meat of the app), and send text messages (thank you, Twilio!)


Hao advised us that since we didn’t have anything to actually show the audience, we shouldn’t present any tech at all. We just let him talk about how awesome the app is, and then I took questions about our plans for expansion. And we ended up taking 3rd place out of 12!

As far as I can tell, there are no press releases announcing the winners. But it’s all over my twitter.

I wrote a short description of our app, in case anyone is interested.

Free Stuff Fairy is a web/mobile app that connects unwanted goods–potential waste–with people who need them. It encourages the reuse of goods in New York City by making the exchange fun and easy. It dynamically generates peer-to-peer offers using a distance-based algorithm. The closest users have the first opportunities to claim an offer. Once a match has been made, Free Stuff Fairy sends a text message (through the Twilio API) to let the recipient know that they’ve been chosen for a certain item. They can then accept or reject the offer within the given time limit.  

My favorite code from the weekend was Jesse’s distance algorithm:

class Matcher
  DELTA = 0.003

  def self.match_user_to_available_item(user)
    lat = user.latitude
    lng = user.longitude
    item = Item.available
      .where('latitude BETWEEN ? AND ?', lat-DELTA, lat+DELTA)
      .where('longitude BETWEEN ? AND ?', lng-DELTA, lng+DELTA)
      .first
    if item
      item.update(status: :unavailable)
      item.offers.create!(owner_id: item.user_id, recipient_id: user.id)
    end
  end

  def self.match_item_to_available_user(item)
    lat = item.latitude
    lng = item.longitude
    user = User.where('latitude BETWEEN ? AND ?', lat-DELTA, lat+DELTA)
      .where('longitude BETWEEN ? AND ?', lng-DELTA, lng+DELTA)
      .without_offer
      .first
    if user
      offer = item.offers.create!(owner_id: item.user_id, recipient: user)
      item.update(status: :unavailable)
      offer
    end
  end
end

Our product is definitely NOT functional yet but we have a plan to meet every night and finish it before BigApps.

FINAL THOUGHTS:

I would really not advise that anybody go to a hackathon until we’re a bit more experienced. My friends agreed that I could approach this one as a student, and I definitely don’t think I was slowing Jesse down (if anything I was helping him debug his code by asking a million questions), but I wish I had more to contribute to my team. Also, sleep deprivation.

Take Web Scraping Further with Mechanize

Recently, the class learned how to use Nokogiri to scrape webpages. A quick Google search reveals that this is indeed the most popular web scraping gem. But many people combine Nokogiri with another gem, Mechanize, to extend its functionality by automating some of the work of clicking the “next” button or creating profiles. This post is a quick writeup of my experiences with Mechanize. Please note that I ended up using Mechanize instead of Nokogiri, not in conjunction with it. This made parsing my html way more complicated than it had to be.

I followed a few different tutorials to do it, including this and this.

I created an example file, "mechanize_example.rb", to run from the command line. The ReadySteadyCode tutorial provides the following code snippet for getting a random wikipedia article and printing it to the terminal:

require 'mechanize'

mechanize = Mechanize.new

page = mechanize.get('http://en.wikipedia.org/wiki/Main_Page')

link = page.link_with(text: 'Random article')

page = link.click

puts page.uri

The #link_with method is provided by mechanize, and makes it easy to pull out the random article link. The #click method instructs mechanize to follow the link, and the #uri method returns the address of the page. Notice that mechanize follows redirects automatically, so this example makes three HTTP requests in total.

I decided to see how far I could take this example by modifying the code to generate interesting data from other websites with “random” functions.

First, a simple change. I swapped out Wikipedia’s info for Reddit’s (I spend entirely too much time on Reddit anyway.) I was able to print random subreddits to my command line.

require 'mechanize'

mechanize = Mechanize.new

page = mechanize.get('http://www.reddit.com/')

link = page.link_with(text: 'random subreddit')

page = link.click

puts page.uri

This code yields such glorious random subreddits as http://www.reddit.com/r/CrossStitch/ and http://www.reddit.com/r/AntiAntiJokes/.

But what else could I do besides print random urls to the command line? Could I also use it to give me the title of the top link on each page? Hint: yes.

require 'mechanize'

mechanize = Mechanize.new

page = mechanize.get('http://www.reddit.com/')

link = page.link_with(text: 'random subreddit')

page = link.click

first_link = page.search '/html/body/div/div/div/div/p/a'

puts page.uri
puts first_link.first.text.strip

Here’s where not using Nokogiri came back to haunt me: look at how complicated parsing the html had become. I was also getting error messages whenever the subreddit was empty (that means it contains no links.) But my command line printouts now magically included results like:

http://www.reddit.com/r/cincinnati/ Just framed this 1902 map up for my dad

and

http://www.reddit.com/r/Images/ Returned to my friends car to find this letter from 7 year old Justin

This idea can be taken so much further! I plan to extend it in the future by taking to the web and creating a game where people can vote on randomly generated subreddits that are pitted against each other. We’ll see which ones are the most popular by name alone.

I might also be able to use Mechanize to create a reddit bot that responds to regular expressions, but we’ll leave that for a theoretical time in the future when I understand regular expressions.

Edit:

Due to popular demand, I’ve turned the subreddit generator into a gem! See: https://rubygems.org/gems/subreddit

Map vs Collect, and Other Ruby Synonyms

Ruby has a ton of high-level iterators. So how are you supposed to know which one to use when? More specifically, what’s the difference between map and collect? They each produce a new array containing the results of the block applied to each element of the receiver. Both map! and collect! are offered to modify the array in place.

Some sources assert that the two methods are the same. Both are array methods that can work with anything that is Enumerable. Ruby is written in C, and the C-level implementation is identical. Here is that implementation:

image

But then why have both? 

Wikipedia explains that Ruby provides both to make programmers feel more comfortable. Map is provided by many programming languages, and collect came from a language called Smalltalk

Other Ruby synonyms include the shovel operator << and concat. The shovel is different than += because += creates a new String in memory, but << is faster because it just modifies the original one

The for loop vs each appear to be synonyms but there is a scoping difference. The local variable used in for loops still exists after the loop, which might have some unintended consequences for your program.

image

On a different note, .size is an alias for .length. But count, which seems similar, is actually different

image

When the inventor of Ruby, Matz himself, was asked to explain why he provides so many ways to do the same thing, he said:

Ruby inherited the Perl philosophy of having more than one way to do the same thing. I inherited that philosophy from Larry Wall, who is my hero actually. I want to make Ruby users free. I want to give them the freedom to choose. People are different. People choose different criteria. But if there is a better way among many alternatives, I want to encourage that way by making it comfortable. So that’s what I’ve tried to do. Maybe Python code is a bit more readable. Everyone can write the same style of Python code, so it can be easier to read, maybe. But the difference from one person to the next is so big, providing only one way is little help even if you’re using Python, I think. I’d rather provide many ways if it’s possible, but encourage or guide users to choose a better way if it’s possible.

So that’s the answer. When presented with two or three or twelve different ways to do the same thing in Ruby, you should choose whichever way makes you the most comfortable.