Build, Break, Learn.

Adam Waxman's technical blog

How to Create an Angular App Using Yeoman and Deploy It to Heroku

| Comments

Step 1: Install Yeoman

Yeoman is a tool to help easily create new projects. You can use its generators to create all different types of web apps (Angular, Backbone, Ember, and many more).

Having node and npm installed on your computer is a requirement for using Yeoman. If you do not have the installed on your computer, follow these installation instructions here.

Once node and npm are installed, install Yeoman by running npm install -g yo.

Step 2: Create an Angular App using the Yeoman Anglar Generator

Now that Yeoman is installed, you can easily create an Angular app by following the instructions below. These are taken from the yeoman angular generator repo readme, which can be found here.

Install generator-angular: npm install -g generator-angular.

Make a new directory and cd into it: mkdir project-name && cd project-name.

Create the angular app: yo angular [app-name] (the app name parameter is optional).

You will be asked if you want yeoman to install SASS (with Compass), Twitter Bootstrap, and include various angular modules. You can learn more about these opitons under the “Configure your generator” here. Below I do not install SASS or Bootstrap, but do include the various angular modules, so I type y, y, and then press enter.

After letting yeoman do its magic, you can run the app locally with the following command: grunt serve.

You should now see something like this on localhost:9000:

Step 3: Add a Server to the App

This step is taken primarily from Brad Barrow’s awesome tutorial, with some slight updates to make it work using the latest version of Express (a web development framework for node.js).

As Brad explains, the angular app created by Yeoman is static, so we can’t expect it to work on Heroku out of the box. In order for Heroky to be able to serve the pages for us we need to add a server to the app.

The server’s dependencies include Gzippo, Morgan, and Express.

To install these dependencies run npm install gzippo express morgan --save.

Next, create a server file called web.js in the room director /web.js.

1
2
3
4
5
6
7
8
var gzippo = require('gzippo');
var express = require('express');
var morgan = require('morgan');
var app = express();

app.use(morgan('dev'));
app.use(gzippo.staticGzip("" + __dirname + "/dist"));
app.listen(process.env.PORT || 5000);

Now that the server file has been created, we need grunt to build the /dist directory that we are serving in line 6 of our web.js file.

We can create this directory by running grunt build.

Step 4: Add Heroku Dependencies

By default the dist that we just createdis included in the .gitignore file:

Since Heroku uses git to deploy, we need to remove dist from the .gitignore file. As Brad explains nicely in his tutorial:

“It’s worth noting that the dist/ directory is ignored by git by default (they assume you only want to version control the development project, not the compiled app). Since Heroku uses git to deploy, we’ll need to remove dist/ from .gitignore to make sure it gets committed.”

Note: While this gets the app up and running on Heroku, it is bad practice to version control the compiled app. I looked around but couldn’t figure out how to compile an angular app on the server on Heroku. If anyway knows of a good way to do this I’d love to hear from you and add it to this post!

Next, we need to turn the project directory into a git repo by running git init.

In addition to making it a git repo we need to create a Procfile, which Heroku uses to understand how to start the app.

Create the Procfile in the root directly just like the web.js file and inlcude the following line, which tells Heroku to use NodeJS to run our web.js file.

web: node web.js.

The next step requires that you have a Heroku account and the Heroku Toolbelt installed. You can get setup with a Heroku account here and download the Heroku Toolbelt here.

Once you have a Heroku account and the Heroku Toolbelt installed, you can create a Heroku app by running:

heroku create <your_app_name>.

The next step is to commit all the code and push it to Heroku:

1
2
3
git add .
git commit -m "Create angular app using Yeoman"
git push heroku master

You need at least 1 web worker to get your app running. You can scale your Heroky web worker to 1 by running the following command:

heroku ps:scale web=1

Ta da, now your app should be running at <your_app_name>.herokuapp.com. To quickly open your app run heroku open

Let me know if you have any questions or any problems while setting up and deploying your app!

Getting Into CSS3 Animations

| Comments

I recently had the opprtunity to dive into some CSS3 animations. I’ve used libraries like animate.css and done animations with javascript, but never did any custom CSS3 work

The Task

We recently updated our ‘tracking’ iconography at SeatGeek to match our new iPhone app. The lead designer created the heart icon with different states in a PSD and also created the animation below:

What is CSS3 Animation?

In CSS, animation is an effect that lets an element gradually change styles. You create the animations with the @keyframes keyword, which is followed by the name of the animation.

1
2
3
@keyframes heartAnimation {
  /* Animation code goes here */
}

To make the animation cross browser compatible you need to use vendor prefixes:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@keyframes heartAnimation {
  /* IE 10+ */
}

@-webkit-keyframes heartAnimation {
  /* Safari 4+ */
}

@-moz-keyframes heartAnimation {
  /* Fx 5+ */
}

@-o-keyframes heartAnimation {
  /* Opera 12+ */
}

However, for the rest of this post I will exclude the vendor prefixes for the sake of space.

The next step is to add the animation effects and decide when they happen. You can do this with either percentages from 0% to 100% or with the ‘from’ and ‘to’ keyword for simple animations with just a starting and ending state. Below is an example for changing the background color from yellow to blue, and then yellow to green to blue.

1
2
3
4
5
6
7
8
9
10
@keyframes colorChange {
  from {background: yellow;}
  to   {background: blue;}
}

@keyframes colorChange {
  0%   {background: yellow;}
  50%  {background: green;}
  100% {background: blue;}
}

Once the keyframes are created, you can call the animations as CSS properties. For example the code below would run the colorChange animation above 2 times for a 2s duration:

1
2
3
4
5
6
7
8
9
10
.color-animation {
  animation-name: changeColor;
  animation-iteration-count: 2;
  animation-duration: 2s;
}

/* Shorthand */
.color-animation {
  animation: changeColor 2 2s;
}

You can check out all the CSS3 animation properties here

Planning Out the Animation

After watching the gif several times, I realized it was a slight contraction followed by an expansion to a size slightly larger than the original size, and then back to the original size.

Heart Clicked Animation

Using the CSS3 keyframes and animation syntax above, here is the code I used to make the animation in the gif at the top of this page. It uses the css transform and property to scale the image.

1
2
3
4
5
6
7
8
9
10
@keyframes heartAnimation {
  0%  {transform: scale(1,1)}
  20% {transform: scale(0.9,0.9)}
  50% {transform: scale(1.15,1.15)}
  80% {transform: scale(1,1)}
}

.toggle-animation {
  animation: heartAnimation 0.7s; // no iteration count is needed as the default is 1 time
}

For the image, I was using a sprite, so I also needed to change the position of the image to get the red background:

1
2
3
4
.toggle-animation {
  background: url('../images/animation-example-sprite.png') no-repeat -320px 0;
  animation: heartAnimation 0.7s; // no iteration count is needed as the default is 1 times
}

Loading Animation

For a loading state, I made the heart white and pulsate in-and-out infinitely. It also scales down and back to the original size, instead of getting slightly larger than the original size before going to the original state like in the heartAnimation code above. Below is the code for the loading state:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@keyframes loading {
  0% {transform: scale(1,1) }
  50% {transform: scale(0.8,0.8) }
  100% {transform: scale(1,1) }
}

/* Notice the added 'infinite' to is used to make the animation-iteration-count */

.toggle-loading {
  background: url('../images/animation-example-sprite.png') no-repeat -160px 0; // make background white
  animation: loading 1s infinite;
  -webkit-animation: loading 1s infinite;
  -moz-animation: loading 1s infinite;
  -o-animation: loading 1s infinite;
}

Check Out Demos of the Animations

Here is a site I built to demo the animations:

http://heart-animation.herokuapp.com/

Below is the JS I used to make the animations happen when each icon is clicked. The JS adds and removes the classes that I added the animation properties to.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$(document).ready(function(){

  $('.animation-1 .image').on('click', function(){
    $(this).toggleClass('toggle-animation');
  });

  $('.animation-2 .image').on('click', function(){
    $(this).toggleClass('toggle-animation-slow');
  });

  $('.animation-3 .image').on('click', function(){
    $(this).toggleClass('toggle-loading');
  });

});

Sorting a Rails Resource Based on a Calculated Value

| Comments

The Setup

I recently went to a mobile payments hackathon and worked on a reminder app with my co-founder of Flock. You input the name of your item and the day of the month that it’s due. The app then shows you how long you have to complete the given task based on a green to red spectrum inspired by Clear.

Being a hackathon project, we wanted to keep the app simple. It contained a Reminder model with 2 attributes: 1) name and 2) day of the month you want to complete the task.

The Problem

I got to a point where I wanted to sort the items by number of days left until the item was due.

If I had a column in the database called ‘days_until_due’ I could have used the order method:

1
Reminder.order('days_until_due ASC')

But I didn’t have a database column called ‘days_until_due’…

This got me asking myself, “What’s the best way to sort a model based on a calculated value instead of a value stored in the database?”

The Solution

After googling around I stumbled upon a nice solution. It suggested creating an instance method to calculate the value, and then creating a class method that combines a query with the sort_by method.

Step 1: Create an instance method to calculate the value

In reminder.rb, I created an instance method to find out how many days until the item is due based on the day of the month the item was suppoed to be completed by and the current date:

1
2
3
4
5
6
7
8
9
10
11
def days_until_due
  today = Time.now
  simple_today = Time.new(today.year, today.month, today.day)
  if day >= today.day
    month_due = today.month
  else
    month_due = today.month + 1
  end
  day_due = Time.new(today.year,month_due,day)
  return ((day_due - simple_today)/(60*60*24)).to_i
end
Step 2: Create a class method to query and sort the model

Again in reminder.rb, I then created a class method, which combined a query, sort_by, and the instance method from above.

1
2
3
def self.sorted_by_days_until_due
  Reminder.all.sort_by(&:days_until_due)
end

You may be asking yourself what is going on in that one line method? Let’s break it down step by step. First, Reminder.all returns an array of all the reminders (unsorted).

1
Reminder.all.class # => Array

Next, I call the sort_by method on this array. This method takes a block as an argument and generates a sorted array by mapping the values through the given block. If no block is given, an enumerator is returned instead. Below is an example:

1
2
3
4
5
array = ["Michael", "Adam", "Jen"]

array.sort_by{|word| word.length} # => ["Jen", "Adam", "Michael"] 

array.sort_by # => #<Enumerator: ["Michael", "Adam", "Jen"]:sort_by>

Now you’re probably asking yourself, but how does ‘&:days_until_due’ translate into a block? It has to do with procs and blocks. If you’re unfamiliar with these terms, you should check out a post I wrote discussing these parts of ruby. In one sentence, the ‘&:’ syntax is converting the instance method into a proc, and then converting the proc into a block, which is what Array#sort_by takes as an argument.

Below I will make the example above look like the method I used in my reminder app.

1
2
3
4
5
6
7
8
9
10
11
array = ["Michael", "Adam", "Jen"]

# Passing in a block directly
array.sort_by{|word| word.length} # => ["Jen", "Adam", "Michael"] 

# Creating a proc and converting the block to a proc using the '&' syntax
proc = :length.to_proc # => #<Proc:0x007f98a225f700> 
array.sort_by(&proc) # => ["Jen", "Adam", "Michael"]

# Creating a proc and converting the block to a proc in one step
array.sort_by(&:length) # => ["Jen", "Adam", "Michael"]

The above syntax works by combining implicit type casting with the ‘&’ operator. The ‘&’ operator is used in an argument list to convert a Proc instance into a block. If you combine the operator with something other than a Proc instance, implicit type casting will try to convert it to a Proc instance using the to_proc method. Since Symbol#to_proc exists, when we pass a symbol after the ‘&’ operator, it is converted into a proc, which is then converted into a block.

Going back to my original problem, all this talk about procs and blocks and type casting is what allowed me to create the following one line method:

1
2
3
def self.sorted_by_days_until_due
  Reminder.all.sort_by(&:days_until_due)
end

This method allowed me to succinctly include a sorted array of reminders in my view with the following:

1
@reminders = Reminder.sorted_by_days_until_due

Now back to coding!

Deploying a Rails App With Capistrano (Part 2)

| Comments

My last post outlined using Capistrano to deploy my 6-week long Flatiron School project. The post included a brief introduction of Capistrano, including what it is and the steps to get a Capfile (where Capistrano reads instructions from) into your app.

In this post, I am going to continue to walk through a basic deploy.rb file. If you don’t know what what a deploy.rb file is you should check out the earlier post first.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
require 'bundler/capistrano' # for bundler support

set :application, "set your application name here"
set :repository,  "set your repository location here"

set :user, 'USERNAME'
set :deploy_to, "/home/#{ user }/#{ application }"
set :use_sudo, false

set :scm, :git

default_run_options[:pty] = true

role :web, "96.8.123.64"  # Your HTTP server, Apache/etc
role :app, "96.8.123.64"  # This may be the same as your `Web` server

# if you want to clean up old releases on each deploy uncomment this:
# after "deploy:restart", "deploy:cleanup"

# if you're still using the script/reaper helper you will need
# these http://github.com/rails/irs_process_scripts

# If you are using Passenger mod_rails uncomment this:
namespace :deploy do
 task :start do ; end
 task :stop do ; end
 task :restart, :roles => :app, :except => { :no_release => true } do
   run "#{try_sudo} touch #{File.join(current_path,'tmp','restart.txt')}"
 end
end

In the previous post I left off with the set ‘:scm, :git line’, so I will start with the following line:

1
default_run_options[:pty] = true

This is included to make sure Capistrano interacts properly with the shell on our server. For example, when using github your server needs to be able to access your repo. This capistrano config settting is needed for the password prompt from git to work so you can access it.

1
2
role :web, "96.8.123.64" # Your HTTP server, Apache/etc
role :app, "96.8.123.64" # This may be the same as your Web server

The above two lines assign the web and app ‘roles’ to specific servers. Capistrano roles allow you to have different servers handle different parts of the app (server for app, server for handling requests, and server for the database). We used one server for all aspects so assigned all roles to the same server.

Since we used Passenger, we also uncommented the :deploy namespace as is instructed in the standard deploy.rb file. This part of the file is an example of Capistrano’s task-oriented nature. Similar to rake tasks, we can create ‘cap’ tasks with the task keyword. For example, take the following 3 lines of code:

1
2
3
task :hello do
  puts "Hello World"
end

We can run this code with the following command in the terminal:

1
cap hello

We also used a common capistrano task to symlink specific files that were purposely excluded from our git repo. For example, we had an application.yml file with our Crunchbase API key and gmail username/password. Since we open sourced the repo, we had to make sure that file was included in our .gitignore. Because capistrano is getting the code from github, we have to manually link these ignored files to the server in order for them to be included. The following task helps us do just that. ruby

1
2
3
task :symlink_config, :roles => :app do 
  run "ln -nfs #{shared_path}/config/application.yml #{release_path}/config/application.yml"
end

In order for the symlink to work though, the file must already be in the shared folder on the server. You can securely copy a file from your local machine using a variation of the following command:

1
scp config/application.yml example@123.456.789.12:/home/example/example_app/shared

And that concludes my Capistrano configuration process. To deploy and update the app I simply run the following command:

1
cap deploy

If you’re interested in learning more about deploying a rails app with Capistrano, there is a good railscast and also a nice wiki on Github.

Deploying a Rails App With Capistrano (Part 1)

| Comments

I recently graduated from the Flatiron School, where I worked on a 6-week long project with a group of 3 other students. Our project, HireMe, is a CRM platform to help manage the interview process. We built the app using Rails and deployed it onto a cloud server using Capistrano (along with Nginx and Passenger). For side projects I’ve used Heroku, so this was my first time deploying to my own server.

What is Capistrano?

Capistrano is a remote server automation and deployment tool written in ruby. Put simply, it helps you get your code on a server and easily run commands on a server so your application is ready for the world to use.

Using Capistrano

The first step in using capitstrano is installing the capistrano gem on your local machine. Capistrano only requires that your have access to your server via Secure Shell (SSH).

1
gem install capistrano

Once the gem is installed the next step is to cd into your repository’s directory and run the following command:

1
capify .

This creates a Capfile, which is where Capistrano reads instructions from. This is what it looks like out of the package:

1
2
3
4
load 'deploy'
# Uncomment if you are using Rails' asset pipeline
    # load 'deploy/assets'
load 'config/deploy' # remove this line to skip loading any of the default tasks

The capify command also creates a file in the config directory called deploy.rb, which the Capfile loads from as you can see above. The deploy file contains information about the servers you want to connect to and the tasks you want to run on those servers.

Below is the default deploy.rb file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
set :application, "set your application name here"
set :repository,  "set your repository location here"

# set :scm, :git # You can set :scm explicitly or Capistrano will make an intelligent guess based on known version control directory names
# Or: `accurev`, `bzr`, `cvs`, `darcs`, `git`, `mercurial`, `perforce`, `subversion` or `none`

role :web, "your web-server here"                          # Your HTTP server, Apache/etc
role :app, "your app-server here"                          # This may be the same as your `Web` server
role :db,  "your primary db-server here", :primary => true # This is where Rails migrations will run
role :db,  "your slave db-server here"

# if you want to clean up old releases on each deploy uncomment this:
# after "deploy:restart", "deploy:cleanup"

# if you're still using the script/reaper helper you will need
# these http://github.com/rails/irs_process_scripts

# If you are using Passenger mod_rails uncomment this:
# namespace :deploy do
#   task :start do ; end
#   task :stop do ; end
#   task :restart, :roles => :app, :except => { :no_release => true } do
#     run "#{try_sudo} touch #{File.join(current_path,'tmp','restart.txt')}"
#   end
# end

We worked off of an awesome deployment guide by Spike Grobstein that recommended starting with the following deploy.rb file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
require 'bundler/capistrano' # for bundler support

set :application, "set your application name here"
set :repository,  "set your repository location here"

set :user, 'USERNAME'
set :deploy_to, "/home/#{ user }/#{ application }"
set :use_sudo, false

set :scm, :git

default_run_options[:pty] = true

role :web, "96.8.123.64"                          # Your HTTP server, Apache/etc
role :app, "96.8.123.64"                          # This may be the same as your `Web` server

# if you want to clean up old releases on each deploy uncomment this:
# after "deploy:restart", "deploy:cleanup"

# if you're still using the script/reaper helper you will need
# these http://github.com/rails/irs_process_scripts

# If you are using Passenger mod_rails uncomment this:
namespace :deploy do
 task :start do ; end
 task :stop do ; end
 task :restart, :roles => :app, :except => { :no_release => true } do
   run "#{try_sudo} touch #{File.join(current_path,'tmp','restart.txt')}"
 end
end

This version differs slightly from the default deploy.rb file, namely adding lines to set the user information, where to deploy to, and a couple other small settings. Below are some exaplanations of each of the lines in this file.

1
set :application, "studentbody"

This code sets the application variable. It will become the name of the overarching folder on the server and is also used in the deploy_to location a couple lines below.

1
2
3
4
set :repository,  "set your repository location here"

#example
set :repository,  "git@github.com:YourGithubUsername/ExampleRepo.git"

The repository variable tells Capistrano where to find your code. We used a github hosted repository.

1
set :user, 'USERNAME'

The above line sets the name of the user we are deploying as. For example if you are SSHing into your server with the following command ‘ssh example@192.241.555.55’ then you’d set :user to example.

1
set :deploy_to, "/home/#{ user }/#{ application }"

This command sets the location of deployment. In the case where the the user is jsmith11 and the app name is example-app, the above code would deploy the app to ‘/home/jsmith11/example-app’ directory on the remote server.

1
set :use_sudo, false

The user_sudo variable tells Capistrano whether or not to prefix sudo infront of all commands. Sudo is a prefix that allows you to run programs with the security priveledges of another user (commonly used with the superuser/root). In our case we were deploying to a location that our user owned, so we set this to false.

1
set :scm, :git

The scm variable sets the source-code-management system, which in our case was git.

In a follow up post I will talk more about the rest of the deploy.rb file, custom tasks we ran in our HireMe app, and getting the app up and running using the ‘cap deploy’ command.

How to Deploy an App in 5 Minutes Using Roots

| Comments

The Ingredients

  • node.js: server-side JavaScript
  • heroku: cloud platform as a service to help you easily deploy your apps
  • roots (the special sauce): a tool for quickly building beautiful and efficient web products

The Steps

1. Install node

If you don’t have node.js, install it from nodejs.org.

2. Install roots

Once node.js is installed, you can can install roots in the terminal with the following command:

1
npm install roots -g # prefix with sudo if you get a permission error

3. Create a new roots project

You can create a new roots project with the following command in the terminal:

1
roots new [name of project] # i.e. roots new new_project

4. Start the local server

Once you’ve switched into the new project folder, you can start the app on localhost:1111 with the following command:

1
roots watch

5. Deploy to heroku

Now you’re one small command away from having your app up on Heroku for the world to see:

1
roots deploy

Yes, it’s that easy. If you don’t believe me checkout the app I made while going through the roots tutorial.

Checkout your own app with the following command:

1
heroku open

Note: The standard homepage markup is placed in a views folder with the name ‘index.jade’. If you don’t want to use the default roots stack (jade, stylus, and coffeescript), you can revert to an html, css, and javascript stack by adding the —basic flag to your roots new command.

Awesome features

In addition to helping you get an app up and running in just a couple minutes, roots also has a ton of amazing built in features.

LiveReload: lets you see your markup and styling changes without having to refresh your browser Axis | Better CSS: a css library built on top of stylus that helps take the pain out of traditional css

Axis in action

An example of how Axis makes css easier is how it simplifies border radius. The following code shows how to create a border radius that works across different browsers: first using standard css, and then using Axis.

1
2
3
4
5
6
7
8
9
10
/* Standard css border radius styling */
div {
  -webkit-border-radius: 5px;
  -moz-border-radius: 5px;
  border-radius: 5px;
}

/* Using axis to add a border radius */
div
  border-radius: 5px; /* vendor prefixes are added automatically */

The button in the example page uses the following code:

1
2
3
.button a
  simple-button: blue 15
  transition()

Border-radius? Included. An easy on the eyes blue? Included. Darken on hover? Included. Yep, it’s super convenient. There are a lot of other cool features you can check out via the library’s documentation.

This is just the tip of the iceberg

There are a lot of other awesome features that I haven’t talked about above – for example dynamic content and js templates. The roots creator, @jescalan, has some great video tutorials that you can find here if you are interested in learning more.

What Is the Difference Between a Block, a Proc, and a Lambda in Ruby?

| Comments

What are blocks, procs, and lambdas?

Coder Talk: Examples of closures in ruby.

Plain old english: Ways of grouping code we want to run.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# Block Examples

[1,2,3].each { |x| puts x*2 }   # block is in between the curly braces

[1,2,3].each do |x|
  puts x*2                    # block is everything between the do and end
end

# Proc Examples             
p = Proc.new { |x| puts x*2 }
[1,2,3].each(&p)              # The '&' tells ruby to turn the proc into a block 

proc = Proc.new { puts "Hello World" }
proc.call                     # The body of the Proc object gets executed when called

# Lambda Examples            
lam = lambda { |x| puts x*2 }
[1,2,3].each(&lam)

lam = lambda { puts "Hello World" }
lam.call

While it looks like these are all very similar, there are subtle differences that I will cover below.

Differences between Blocks and Procs

  1. Procs are objects, blocks are not
  2. A proc (notice the lowercase p) is an instance of the Proc class.
    1
    
    p = Proc.new { puts "Hello World" }
    
    This lets us call methods on it and assign it to variables. Procs can also return themselves.
    1
    2
    3
    4
    
    p.call  # prints 'Hello World'
    p.class # returns 'Proc'
    a = p   # a now equals p, a Proc instance
    p       # returns a proc object '#<Proc:0x007f96b1a60eb0@(irb):46>'
    

    In contrast, a block is just part of the *syntax* of a method call. It doesn’t mean anything on a standalone basis and can only appear in argument lists.
    1
    2
    3
    
    { puts "Hello World"}       # syntax error  
    a = { puts "Hello World"}   # syntax error
    [1,2,3].each {|x| puts x*2} # only works as part of the syntax of a method call
    
  3. At most one block can appear in an argument list
  4. In contrast, you can pass multiple procs to methods.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    def multiple_procs(proc1, proc2)
      proc1.call
      proc2.call
    end
    
    a = Proc.new { puts "First proc" }
    b = Proc.new { puts "Second proc" }
    
    multiple_procs(a,b)
    

Differences between Procs and Lambdas

Before I get into the differences between procs and lambdas, it is important to mention that they are both Proc objects.

1
2
3
4
5
proc = Proc.new { puts "Hello world" }
lam = lambda { puts "Hello World" }

proc.class # returns 'Proc'
lam.class  # returns 'Proc'

However, lambdas are a different ‘flavor’ of procs. This slight difference is shown when returning the objects.

1
2
proc   # returns '#<Proc:0x007f96b1032d30@(irb):75>'
lam    # returns '<Proc:0x007f96b1b41938@(irb):76 (lambda)>'

The (lambda) notation is a reminder that while procs and lambdas are very similar, even both instances of the Proc class, they are also slightly different. Below are the key differences.

  1. Lambdas check the number of arguments, while procs do not
  2. 1
    2
    3
    4
    
    lam = lambda { |x| puts x }    # creates a lambda that takes 1 argument
    lam.call(2)                    # prints out 2
    lam.call                       # ArgumentError: wrong number of arguments (0 for 1)
    lam.call(1,2,3)                # ArgumentError: wrong number of arguments (3 for 1)
    
    In contrast, procs don’t care if they are passed the wrong number of arguments.
    1
    2
    3
    4
    
    proc = Proc.new { |x| puts x } # creates a proc that takes 1 argument
    proc.call(2)                   # prints out 2
    proc.call                      # returns nil
    proc.call(1,2,3)               # prints out 1 and forgets about the extra arguments
    
    As shown above, procs don’t freak out and raise errors if they are passed the wrong number of arguments. If the proc requires an argument but no argument is passed then the proc returns nil. If too many arguments are passed than it ignores the extra arguments.

  3. Lambdas and procs treat the ‘return’ keyword differently
  4. ‘return’ inside of a lambda triggers the code right outside of the lambda code
    1
    2
    3
    4
    5
    6
    7
    
    def lambda_test
      lam = lambda { return }
      lam.call
      puts "Hello world"
    end
    
    lambda_test                 # calling lambda_test prints 'Hello World'
    
    ‘return’ inside of a proc triggers the code outside of the method where the proc is being executed
    1
    2
    3
    4
    5
    6
    7
    
    def proc_test
      proc = Proc.new { return }
      proc.call
      puts "Hello world"
    end
    
    proc_test                 # calling proc_test prints nothing
    

So what is a closure?

Coder Talk: ‘A function or a reference to a function together with a referencing environment. Unlike a plain function, closures allow a function to access non-local variables even when invoked outside of its immediate lexical scope.’ – Wikipedia

Plain old english: Similar to a suitcase, it’s a group of code that when opened (i.e. called), contains whatever was in it when you packed it (i.e. created it).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Example of Proc objects preserving local context

def counter
  n = 0
  return Proc.new { n+= 1 }
end

a = counter
a.call            # returns 1
a.call            # returns 2

b = counter
b.call            # returns 1

a.call            # returns 3

Background Part 1: Lambda Calculus and Anonymous Functions

Lambda get its name from a type of calculus introduced in the 1930s to help investigate the foundations of mathematics. Lambda calculus helps make computable functions easier to study by simplifying its semantics. The most relevant of these simplifications is that is treats functions ‘anonymously’, meaning that no explicit names are given to functions.

1
2
sqsum(x,y) = x*x + y*y  #<-- normal function
(x,y) -> x*x + y*y #<-- anonymous function

Generally speaking, in programming the term lambda refers to anonymous functions. These anonymous functions are very common and explicit in some languages (i.e. Javascript) and implicit in others (i.e. Ruby).

Background Part 2: Where Does the Name Proc Come From

Proc is short for procedure, which is a set of instructions packaged as a unit to perform a specific task. In different languages these may be called functions, routines, methods, or the generic term callable units. They are usually made to be called multiple times and from multiple times in a program.

Summary Differences

  1. Procs are objects, blocks are not
  2. At most one block can appear in an argument list
  3. Lambdas check the number of arguments, while procs do not
  4. Lambdas and procs treat the ‘return’ keyword differently

How jQuery and AJAX Actually Work

| Comments

As someone who loves UX and design, it is not surprising that I’ve been wanting to learn about JavaScript – the language of the browser that allows for cool client side interactions. I’ve used many JS libraries, but wanted to dive deeper into AJAX. Before today I didn’t even know what it meant, just that it was something I wanted to know more about.

So What is AJAX?

AJAX, or Asynchronous Javascript And XML, is a client side technique for communication with a web server. In other words, it allows you to fetch data ‘in the background’ without having to reload a whole page.

In a typical web request, you send a URL request to the server and the server responds with the corresponding HTML, CSS, and JavaScript that generates a full new page in your browser.

In contrast, in a typical AJAX request, the HTML, CSS, and JavaScript is already loaded. Instead of making a URL request for another whole page, you use JavaScript to talk to the server and receive smaller pieces of information that can range from HTML to other data formats like JSON and XML. The JavaScript then acts on the response and updates the page accordingly, without having to refresh the entire page.

What does an AJAX request look like?

1
$.ajax(url, settings)

At a high level an AJAX request consists of the URL you a making a request to, and then corresponding settings to handle the response. Below are a few of the more popular callbacks that make up the settings:

  • success: what to do if the URL request is successful
  • error: what to do if the URL request is unsuccessful
  • timeout: how long to allow the URL request to run before an error message pops up
  • beforeSend: runs before the AJAX request, good place to put a spinner
  • complete: runs after both success and error, good place to stop a spinner

Examples

1
2
3
4
5
6
/* Example 1 */
$.ajax('index.html', {
  success: function(response) {
    $('.hello-world').html(response);
  }
});

Example 1: makes a request to ‘index.html’ and then inserts the response into the item in the DOM that has a class called “hello-world”

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/* Example 2 */
$.ajax('profile.html?userId=1', {
  success: function(response) {
    $('.show').html(response);
  }
});

/* Example 3 */
$.ajax('profile.html', {
  success: function(response) {
    $('.show').html(response);
  },
  data: {"userId": 1}
  }
});

/* Example 4 */
$.ajax('profile.html', {
  success: function(response) {
    $('.show').html(response);
  },
  data: {"userId": $(".show").data("userId")}
  }
});

/* Corresponding HTML to go with Example 4 */
<div class="show" data-userId="1"></div>

These three examples all make a request to the url ‘profile.html?userId=1’ and show the various ways to send parameters with a request. In example 2 the data is put manually into the URL. In example 3 the data is put into a JavaScript object. Lastly, in example 4 the AJAX request pulls data from HTML, which when combined with ERB tags can make the request very dynamic.

1
2
3
4
5
6
7
8
9
10
11
12
13
/* Example 5 */
$.ajax('index.html', {
  success: function(response) {
    $('.hello-world').html(response);
  },
  timeout: 3000,
  beforeSend: function() {
      $('.hello-world').addClass('is-loading');
  },
  complete: function() {
      $('.hello-world').removeClass('.is-loading');
  }
});

Example 5 demonstrates some of the callback settings. In this AJAX request, if the response is not successfully made it will stop the request after 3 seconds (3000 milliseconds). It also demonstrates common code for adding a loading animation while the request is being made.

Building a Mobile App Landing Page

| Comments

Over the last year I’ve been working on a mobile app called Flock. To get ready for our launch, I created a new landing page to allow people to easily download the app. On a desktop browser, it allows people to input their phone number and receive a text on their phone with a link to download the app. On a mobile device, it allows people to download the app directly.

The Ingredients

  • Twilio: An API to make and receive phone calls and send and receive text messages. I used this service to send a text message to desktop users containing a link to download the app.
  • fancyBox: Tool for displaying images, html content and multi-media in a Mac-style “lightbox” that floats overtop of web page
  • Creative Buttons: Button inspirations from Codrops
  • SASS/Bourbon/Neat:
    • SASS: A CSS extension that adds nested rules, variables, mixins, and selector inheritance
    • Bourbon: A mixin library for SASS
    • Neat: A grid framework for SASS with Bourbon

Sending a Text

My first step was to get the text message part of the landing page working. High level I wanted to be able to send users a text message with a link to download Flock on their iPhone. To do this, I created a form to collect a user’s phone number, and then utilized a Twilio gem to send a message to the collected number.

Using the ‘twilio-ruby’ gem I was able to get a text message up and running relatively quickly by creating a form and adding the Twilio logic in the route associated with that form.

1
2
3
4
5
6
7
8
9
10
11
12
  def send_text
    number = params[:number] # grab user's number from form and assign to 'number' variable
    account_sid = '**********************************' # received after creating an account with Twilio
    auth_token = '********************************' # same as above
    @client = Twilio::REST::Client.new account_sid, auth_token # create a Twilio client (used to send messages)
    @client.account.sms.messages.create( # method on client to create an sms message
      :from => '+15555555555', # my Twilio number in actual code
      :to => number, # user's number
      :body => 'Download Flock and do more together: flockwithme.com/app' # text message content
    )
    redirect_to root_path
  end

Making it Look Pretty Part 1: Adding a fancyBox

I wanted to use javascript on the “SEND ME A LINK” button so that the website didn’t have to load a new page to display the number form. Not wanting to re-invent the wheel, I looked around for js plugins and ended up choosing fancyBox, a library to easily implement “lightbox” popups.

To implement this plugin, there were a couple main steps:

  1. Create a hidden div containing the number form
  2. Link a button to the hidden div
  3. Add the necessary js from fancyBox

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# STEP 1: Add hidden div containing form
# Note: id = "number_form"

<div style="display:none" class="text" id="number_form">
    <%= form_tag(send_text_path, :method => :post) do %>
      <%= text_field_tag(:number, nil, :placeholder => '555-555-5555')%><br>
      <%= submit_tag("Submit") %>
    <% end %>
</div>


# STEP 2: Creata a button that links to the hidden div
# Note: class = "fancybox" and href = "#number_form" (id of div from STEP 1)

<a href="#number_form" class="fancybox"><div>SEND ME A LINK</div></a>

# STEP 3: Add the fancyBox js to show the div when the button is clicked
# Note: I am calling the function "fancybox" on all links
#       that have a class named "fancybox" (from STEP 2)

<script type="text/javascript">
    $(document).ready(function() {
      $("a.fancybox").fancybox({
        maxWidth: 900,
        helpers : {
            overlay : {
                css : {
                    'background' : 'rgba(0, 0, 0, 0.8)'
                }
            },
        }
      });
    });

</script>

Making it Look Pretty Part 2: A Fancy Button

Once I got the fancyBox working, I wanted to customize the styling of the form. Earlier in the week I stumbled across an awesome link from Codrops that had examples of many different buttons using CSS. I chose my favorite and added the appropriate CSS.

The button I chose gives a 3D effect by creating a shadow and making the shadow smaller / shifting down the button while hovering over the button, and removing the shadow all together when clicked.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// Note I am using SASS, which allows me to nest my css

input[type=submit] {
    border: none;
    cursor: pointer;
    width: 100%;
    padding: 15px 0px;
    margin: 15px 0px;
    text-transform: uppercase;
    position: relative;
    background: $green;
    box-shadow: 0 6px #527a52;
    font-family: "proxima-nova", "sans-serif";
    font-style: italic;
    font-weight: 800;
    font-size: 1.2em;
    color: white;
    border-radius: 0 0 5px 5px;

    &:hover{
    box-shadow: 0 4px #527a52;
    top: 2px;
    }

    &:active{
      box-shadow: 0 0 #527a52;
      top: 6px;
    }

  }

Making it Look Pretty Part 3: Responsive Design

Once I got the button looking sharp on a desktop browser, I then wanted to make the page responsive for mobile users. Not only did I want to change the styling so it looked good on a phone, but I also wanted to change the main button so that when a user opens the site on their iPhone the “SEND ME A LINK” button turns into a “DOWNLOAD THE APP” button that takes him or her directly to the App Store.

I made the button (and rest of the website) responsive using Bourbon and Neat. Bourbon is a mixin library for SASS, and Neat is a grid framework for SASS with Bourbon.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// STEP 1: Define a mobile breakpoint (Neat version of CSS media query)
$break_four: new-breakpoint(max-width 585px);


// STEP 2: Define style to hide elements where class = "mobile"

.mobile {
 display: none;
}

// STEP 3: Hide items where class = "desktop" and show 
//         items where class = "mobile" at breakpoint

@include media($break_four) {
  .desktop {
    display: none;
  }
  .mobile {
    display: block;
  }
}

// STEP 4: Add classes where appropriate

<div id="button">  
    <a href="#number_form" class="desktop fancybox"><div>SEND ME A LINK</div></a>
    <a href="http://bit.ly/11LgLAn" class="mobile"><div>DOWNLOAD THE APP</div></a>
</div>

And that’s how to create a simple landing page for a mobile app!

Using the Twitter API to Find People

| Comments

Inspiration

Over the last year I’ve become a huge Twitter fan. So much so that I had to move it off the front page of my phone so I wouldn’t be (as) distracted throughout the day. In addition to my personal account, I have several accounts for projects I’m working on. I use these accounts to discover and interact with people that may be interested in these apps.

To discover people that I think may be interested, I look at recent followers of similar apps. While this process worked alright, it was a very manual. Also, one of the apps I’m working on is only available in NYC, and there was no way to search for people only living in NYC and the surrounding area.

Using the Twitter API

I decided that I could use the Twitter API to help automate this process. For example, let’s pretend that I am creating starting a Ruby Motion meetup in NYC. I’d like to find people in the NYC area that are interested in Ruby Motion. Using Twitter, I can find these people a couple of different ways:

  1. Look for people that follow @RubyMotion
  2. Look for people that recently tweeted “#rubymotion”

In addition to finding people that match either of the criteria above, I also want to make sure they live in the NYC area.

Getting Started

I first looked into the best way to access the Twitter API from a ruby environment. As Twitter is a very popular app, I figured there was likely a good gem. After searching for ‘Twitter’ on www.ruby-toolbox.com, I ended up deciding to go with the ‘Twitter’ gem. After installing this gem in the terminal, I required the rubygems gem and twitter gem in my ruby file.

1
2
require 'rubygems'
require 'twitter'

Next I read the gem documentation on github, and followed the steps to register and authorize my app. After registering my app on the Twitter Developer site, it was just a few lines of code before I was up and running.

1
2
3
4
5
6
Twitter.configure do |config|
  config.consumer_key = "**********************"
  config.consumer_secret = "*****************************************"
  config.oauth_token = "**************************************************"
  config.oauth_token_secret = "*****************************************"
end

Now I was up and running! To tweet about the new meetup was just a simple line away:

1
Twitter.update("Come on out to our Ruby Motion meetup next Tuesday @ 6:30pm!")

Now for finding relevant people:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
nyc_accounts = {}
index = 0
cursor = -1

# Loop through pages 1-10
while index <15 do

    # Iterate through followes
    followers = Twitter.followers("RubyMotion", :cursor => -1)

    # Save the users 
    followers.users.each do |user|
      rubymotion_accounts[user.screen_name] = user.location if user.location.downcase =~ /(nyc|york)/i
    end

    cursor = followers.next_cursor
    index+=1
end

The code above makes a call to the Twitter API to grab the followers for a sprcific Twitter account, in this case RubyMotion. The way the Twitter API works, each call returns an object that contains an array of 20 seperate hashes, which contain information about each of the followers. Because the API rate limits of the Twitter API are relatively small, I decided to loop through only 15 pages of followers.

Next, I went through each Twitter object and added the username and location of the follower if the location contained either nyc or york (using regular expressions). The result is a hash where the keys are usernames and the values are locations for, containing information of people that follow RubyMotion and have a location that contains either ‘NYC’ or ‘York’.

On to the next one:

1
2
3
4
5
rubymotion_accounts_2 = {}

Twitter.search("#rubymotion", :count => 100, :result_type => "recent").results.each do |status|
  rubymotion_accounts_2[status.attrs[:user][:screen_name]]=status.attrs[:user][:location] if status.attrs[:user][:location].downcase =~ /(nyc|york)/i
end

For the second call, I a utilizing the search method, and querying the most recent 100 tweets that contain the #rubymotion tag. This call returns a Twitter object that contains an array of all the tweets. Each item of the array contains a hash with information about the user. I then saved the username and location of the tweeter if the location of that person contained ‘NYC’ or ‘York’ again.

Saving the data into a database:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
require "sqlite3"
require 'open-uri'

db = SQLite3::Database.new "twitter-bot.db"

db.execute <<-SQL
 
  create table twitter_handles (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    twitter_handle TEXT,
    city TEXT
  );
SQL

rubymotion_accounts.each do |handle, city|
  db.execute("INSERT INTO twitter_handles (twitter_handle, city) 
              VALUES (?, ?)", [handle, city])
end

rubymotion_accounts_2.each do |handle, city|
  db.execute("INSERT INTO twitter_handles (twitter_handle, city) 
              VALUES (?, ?)", [handle, city])
end

Lastly, I wrote a schema.rb file to create a table and iterate through the 2 hashes I created above and insert the information into the new data.

Areas of Future Exploration

One problem I kept on running into was exceeding my API rate limit. For example, in the first API call, the reason I only scroll through 15 pages is because the Twitter API only allows me to make 15 calls within a 15 minute window. While finding 300 relevant people seems like a lot, when you add the location constraint it ends up not being that many people. Similarly in the 2nd API call, I only grab the last 100 tweets because that is all the API lets me grab at a time. This made it really hard to find many people that were relevant for this specific search. When I ran this search I actually ended up with no results because, presumably because of the 100 tweets grabbed, no users were located in New York.