Alex MacCaw

by Alex MacCaw

JavaScript programmer, O'Reilly author.

Page 2


Preventing tab-close data loss in JS Web Apps

Often, when you’re building a JavaScript web application, you want to warn the user about any pending Ajax requests before they close the window.

Perhaps you’ve updated the UI before sending an Ajax request to the server, or perhaps you’re making long running background request. Either way you want to warn the user that, if they continue, they may lose data.

Browsers don’t offer an API to automatically block closing tabs (which would be open to abuse), but they do have a rather archaic API to specify a tab close prompt, window.onbeforeunload.

window.onbeforeunload = function(){ return "Don't leave me!"; }; 

As you can see, this isn’t a normal event. You can only have one listener, and it should return a string that is ultimately displayed to the client.

jQuery has a undocumented active property, a integer representing the amount of co-current Ajax requests. We can check this to...

Continue reading →


JavaScript ‘wake’ event

For monocle.io I wanted to ensure that the list of posts is always kept up to date. This is especially a problem when the computer wakes up from a sleep, as the top posts are often way out of date!

It turns out there is no JavaScript wake event. There is an online event, but it doesn’t seem to trigger whenever the computer is sent to sleep and re-awoken.

The only sure fire way I could work out to achieve this, was to run a interval and check that the it was invoked at the expected times. Any delay in an interval invocation indicates that the computer has just slept.

var TIMEOUT = 20000; var lastTime = (new Date()).getTime(); setInterval(function() { var currentTime = (new Date()).getTime(); if (currentTime > (lastTime + TIMEOUT + 2000)) { // Wake! } lastTime = currentTime; }, TIMEOUT); 

You can find the full jQuery plugin here. It triggers a custom wake event on document.

...

Continue reading →


Heroku Staging

Building a staging environment on Heroku is pretty straightforward, especially now they’ve released their new ‘fork’ feature.

To fork your app and ensure that all your assets, environmental variables, and Postgres databases are cloned, simply run:

heroku fork -a yourapp yourapp-staging 

I also recommend automatically deploying the staging server whenever you push to master. This is convenient, as it means you have a up-to-date version of your app always running. Your can test on staging, and then deploy production a couple of times a day.

To automate staging deploys follow the instructions on the github-heroku-pusher project. A GitHub webhook POSTs to your deploy server, which will then deploy your staging environment in the background.

Continue reading →


Dynamic pagination

Pagination over a constantly changing list is hard. Really hard. In fact it should be one of those computer science problems up there with naming and cache invalidation.

The issue especially surfaces in news sites, like Hacker News. The hierarchy of posts is constantly changing. By the time you click ‘next page’, page two has an entirely different set of posts. So how do you ensure that the next page contains what the user expects to see?

Paginating on offset is out, since the valid offset is constantly changing. Paginating on a post’s date is also out, since HN’s sort order is not determined by date, but rather by a dynamic score.

Well one one method is to store every possible sort order in memory. In fact, this is exactly what Hacker News does. When you click 'next page’, HN knows what you’re expecting to see, because it has the particular sort order you’re looking at stored in a...

Continue reading →


SEO in JS Web Apps

JavaScript and search engines have always had a tricky relationship, and SEO is often used as an argument against single page applications. I’m aiming to put some of those misconceptions to rest in this article and show you that it’s perfectly possible to create a pure JavaScript web application and still have good SEO.

To demonstrate, take a look at the search results for Monocle, a single page web app. You can see that even though the application relies on JavaScript, articles are still getting fetched and indexed correctly.

While there are indications that Google’s spiders can index some urls they find in JavaScript, in my experience they haven’t been able to render and index complex JS web apps without a little help. The key to spidering JS apps lies in Google’s Ajax crawling specification.

The Ajax crawling specification was originally intended for JS apps that use the hash...

Continue reading →


How yield will transform Node.js

Node v0.11.2 was released recently, and with it support for v8 generators. Generators can be hard to grasp, but essentially they’re decorated functions that you can execute multiple times and resume execution at different points inside the function.

What this means in practice is that we can get rid of the callback hell that has plagued node applications, and write code in a synchronous style, while it’s executed asynchronously behind the scenes.

Using yield

A code example is worth a thousand words, so let’s dive right in. We’re going to need Node v0.11.2, which you can easily install with nvm.

nvm install 0.11.2 

We’re going to use a promise based server called Mach, and a promise library called Q. Install both of those with npm if you haven’t already.

Since we’re using bleeding edge v8 features, you’ll need to pass the --harmony flag through to Node whenever you invoke it.

node...

Continue reading →


Time to first tweet

At Twitter, one of our key metrics for success was ‘time to first tweet’, the time taken between someone navigating to twitter.com, and seeing the first Tweet in the page. I’ve always thought it a useful metric, as initial interaction speed is vitally important; take too long, and users lose focus and leave.

There seems to be a lot of fear, uncertainty and doubt (FUD) in the programming community around the speed of JS web apps, especially with the initial page load. Server-side generated HTML is making a come-back, indeed Twitter eventually moved back to that away from a stateful client. It seems the single-page-app approach has many vocal opponents.

I’m here to put some of that FUD to rest, and show you that it’s perfectly possible to make JS web apps that load extremely fast. I’m going to show you some of the techniques I used to make monocle.io so fast.

First, a little...

Continue reading →


Regulation and Innovation

Paradoxically, regulation can sometimes result in innovation. Within highly regulated industries, you often get entrenched businesses and monopolies ripe for disruption. While regulation and red tape may strangle fledgling startups, if they can struggle through and overcome it they have a distinct advantage – less competition.

What’s more, regulation is often ‘hackable’. Look hard, and you’ll see lots of startups out there flirting with grey areas and testing the boundaries. Often it requires a startup environment to think outside the box when it comes to interpreting and applying regulations. Most don’t like to talk about it for obvious reasons.

The are three industries that are great examples of this phenomena at work: drones, bio-tech and payments.

Drones

Commercial drones and quadcopters are an exciting area, and the use cases for them are endless. I went round a startup called...

Continue reading →


Memory Management in JS Web Apps

Memory management is a fairly crucial part to building JavaScript web applications, and just because the language has a garbage collector it doesn’t absolve you from all duties.

Take your classic controller (or view in Backbone land). In its constructor it may bind to some model events, perhaps re-rendering itself when a record changes. You’ll need to clean up these events listeners at some stage, especially if you’re constantly instantiating and removing the controller.

Backbone and Spine have a ‘remove’ method which, behind the scenes, will remove the controller from the DOM via jQuery. Backbone will even cleanup any event handlers using it’s Event.fn.listenTo feature. However, calling this manually whenever we want to remove a controller is a bit onerous, and means we can’t use features like jQuery.fn.html() to remove controllers. We somehow need to detect when the controller’s...

Continue reading →


Queuing Ajax Requests in JS Web Apps

Queueing Ajax requests in JavaScript Web Apps can be important, especially if the interface doesn’t always represent database state.

In both Backbone and Spine, the default behavior is to update the user-interface before sending requests to the server, i.e. an asynchronous user-interface. However, this can cause race conditions. For example:

  1. User creates a record, say a page
  2. Interface is updated and an POST request is sent
  3. User immediately deletes page
  4. DELETE request is sent to the server
  5. The server responds to the DELETE request before the POST request to create the page has finished.
  6. Server 404s because it can’t find the referenced page by ID

The solution to this race condition is to queue Ajax requests, particularly destructive ones (POST, PUT, DELETE). I’ve written a very simple jQuery 1.9 plugin to do just this. All you need to do is pass a queue flag when creating Ajax...

Continue reading →