In improve this we take a look at a reader submitted test, user interface, story or block of code and we try and improve it, without context, explaining what we did as we went.

In this issue, Mike sent a link to an event source to a realtime social media visualization.

Before we ever apply brainpower, let’s apply computer power. JSLint and JSHint are both tools to find mistakes and oversights.

The implied globals are all OK. The unused variables are not. We see immediately that:

  1. The mongo dependency isn’t used
  2. There is no error handling around inserting records into the database.

The first problem is easily solved. The second problem we’ll report and ignore, because it appears throughout the rest of the program:

Let’s apply brainpower. Three things stand out:

  1. map_tweet_to_event seems to have an unnecessary callback. This should be an easy fix.
  2. tweet.coordinates is both null-checked and uses magic numbers. This isn’t a problem; but, data structures with optional nulls are easy to trip on in normal use and complicate testing.
  3. start_streaming is a set of deeply nested callbacks. This one is four levels deep. Not a serious offence by Javascript standards; but, we can do better.

Sadly, this code came with no tests. We write a characterization test to give confidence that we won’t break anything. The bottom of nested callbacks are good places to find expected behaviors:

We flesh out the test guided by the test failures.

Now, we can refactor with (more) confidence:

First, we collapse the map_tweet_to_event callback.

Second, we split up start_streaming up by responsibility. Those responsibilities— right now— are:

  1. Streaming tweets.
  2. Logging.
  3. Filtering tweets.
  4. Saving raw tweets.
  5. Saving events (processed tweets).

1 through 3 involve the Twitter stream. 4 and 5 involve the database.

We create a stream_tweets function:“ ,

Notice we inline the params object that was previously initialized in track_current_user because it is only used by the Twitter.stream method.

Then, we create a record_tweet function:

This function returns the callback function, but keeps the db in scope. Finally, we update track_current_user:

The tests pass! That means it works, right? ;–)

Do you have something you want improved? Send it to p2@thoughtworks.com.