Using $.Deferred to Group AJAX Requests

I am working on a project that contains a lot of charts. Since the data driving the charts could take some time to load I am making each chart load asynchronously using jQuery's ajax functions.

This has worked great, but I noticed that some of the charts are using the same dataset, just charted differently causing the same data to be requested multiple times from the server. One way to handle the duplicate requests is to use the jQuery Deferred Object when making requests.

In order to group the requests together I needed a way to determine if I already have one just like the request going through. To make this simple I used a MD5 library and JSON.stringify() to create a hash of the data that I am sending to the server.

If the hash is unique then I add a deferred object and make the ajax call. Otherwise, I bind to the previous deferred object and wait for the request to finish. Since we are using the jQuery Deferred object the callback will still have the data even if there is a gap between the original ajax request.

Here is a simplified example:

Posted on 14 Feb 2012

How To Make A Snowball

Yeti: Start a Snowball Fight

Earlier I talked about why I created Yeti, the simple debt snowball calculator. Now I am going to talk about some of the technical decisions that went into the initial release.

Ingredients

To start off, here is my ingredient list for Yeti:

Simplicity

The main goal of Yeti is to be simple.

I have removed anything that is not essential to snowballing. There are a lot of things that I 'could' do that I won't because they would cause undue complexity.

Forgiving

One philosophy of form design that I strongly agree with is to be slow to anger and quick to forgive.

Even though there are many ways to have invalid input I try to only show error messages to the users when they have navigated away from an element so that they are not being bugged about something that they are in the middle of changing.

At the same time I tried to build in some unobtrusive functionality to make things a bit easier for data entry. Things such as automatically calculating the minimum payment for a loan and increasing the repayment amount when it is no longer enough to cover the minimum payments.

Repeat customers

The nature of Yeti is to be useful over a long period of time. Since most people will have debt that takes many months, even years, to pay off it would be annoying to have to re-enter the debt information each time they want to perform a checkup on their progress.

To that end, there is an option to save the information for later use. Rather than have a server setup to store the data and having to worry about overhead and privacy of storing the debt information Yeti is using localStorage to store the debt and payment information.

This makes the data specific to the browser, but it makes things a lot less complex and is completely optional for those who would like to use it.

Almost too fast

One of the awesome things about doing all the calculations locally is that they are done really quickly. In early tests it was calculating an entire strategy in about 3ms.

Part of the original design was to have a button that could be used to calculate the snowballing after you make changes. Since the calculations were so fast I removed the button and just listened for the input to change. Every time the input changes the values are checked to make sure they meet some basic rules then the repayment schedule is calculated and the results are updated. Since any change to the data updated the calculations you could watch as you change numbers and see the graph and numbers change almost instantly.

While it was awesome to watch, many of the modern browsers have built in spinners for the HTML5 number inputs. This allows you to press the up/down arrows to change the value of the field. With the calculations happening on the value change, you could hold down the up arrow on the repayment amount and watch the chart morph as the debt was paid off faster. It was quite fun to watch!

The down side is that when multiple large loans were added the calculations couldn't keep up with the constant stream of input changes so the browser would lag trying to catch up. This makes for a definite bad experience.

To prevent the browser from stalling a pause was put in place to only update the calculations when there has been no changes for 100ms. Now you can hold down the up/down arrows and the calculations will be only be updated when you take your finger off for more than 100ms and the browser stall goes away.

Try it.

So what are you waiting for? Go check it out: Ball of Snow.

Also checkout Yeti on Github!

Posted on 9 Dec 2011

Yeti Hunting

Yeti: Start a Snowball Fight

I just released a simple debt snowball calculator: Ball of Snow.

Since college I have had many conversations about the best way to pay off student loans, credit cards, and mortgages.

If you only have a single debt, the answer is simple, spend more--pay it off sooner and save interest. The more debts that you have, the trickier it is.

A common approach is to use a debt snowball to gain momentum by focusing on single loans at a time and keeping the debt repayment amount constant after each is paid off. This creates a "snowball" effect where the money you were spending on a loan gets added to the next loan repayment and the "snowball" gets larger--debts get paid faster. Simple idea and a good way to pay off debts quickly. But did you know that the order that you pay off debts changes how much money you can save on interest?

This project is not the first time that I have attempted to make a debt snowball calculator. It is my third attempt.

For my first attempt, I tried to learn how to use Adobe AIR to make a desktop application that people could use to track their debt and keep updating. I had a lot of plans for it: multiple accounts, nice, pretty charts, fancy interface, cool background articles, etc. That app didn't make it very far. I got the basics done enough that I could show an amortization and simple chart, but there were some technical obstacles that I did not have the time or energy to work out and the desire to finish it floundered.

A year or two later I was out of college and starting my first job as a graduated citizen... with graduated student loans. This spurred my second attempt at a debt snowball application. Similar to the first attempt, I had grand ideas and visions for features. This time I decided to use a server side application and just run it as a normal web application. Things started out pretty good, but there were some major downsides that turned me off to finishing it. It was slow, I did not have a place to host it, and no time to make it into my 'dream' snowball application. So I used it to help get myself out of debt (going on 18 months without debt!) and that is as far as it went.

Since I have been debt free I have not really thought about the debt snowball idea for a while. It was a thing of my past, like a shed snake skin that I didn't have a use for anymore. But I was talking with an old co-worker and friend about the idea of debt snowballing and it got my brain going again. Even though I do not need to use it on my own debt, I still talk to many friends and family about repaying their debt and I am excited when I get to help people save money, especially when it is something as simple as paying debt off in a different order.

Using this fresh batch of excitement I gave the snowball calculator another go. But this time I decided to approach it differently to avoid my earlier mishaps:

  • Simple. I wanted to shed a lot of the complex ideas that would make it a burden to develop and never get 'done'.
  • Fast. My first attempts were a lot slower than I wanted them to be, taken many seconds to process each change. I wanted this project to be fast!
  • Scalable. If the service started getting heavy use I didn't want to worry about the hosting strain from a successful project.
  • Simple. Did I mention simple?

With this in mind, I made a single page JavaScript debt snowball calculator. Since is a single page with no login, optional local storage, and a limited UI/feature set I could ignore a lot of the original complexities. With no dynamic server processing (everything is done with HTML5, JavaScript, and CSS in the browser) it would not have to wait for page submissions/ajax requests to show the calculations. And since I was able to use Github pages to host the site it was free, scalable, and quick loading.

With my third attempt, I hope to catch the great snow beast and make it easy to understand debt snowballing.

Its free, fast, and fun to experience. I hope you enjoy it as much as I enjoyed creating it!

So what are you waiting for? Go check it out: Ball of Snow.

Posted on 8 Dec 2011

Combining the Cicada Principle with CSS3 Background Gradients

Lately I have been trying to use CSS as much as possible without having to make images, especially for backgrounds. A few months back I read about the cicada principle as it relates to design. It was a fascinating read, if you haven't read it already, you should do yourself a favor and read it now. Also check out their cicada gallery for interesting examples of the cicada principle in action.

In the example, the author uses png images and repeats them. I wanted to try and do something similar but done purely in CSS. I found some really good resources dealing with CSS 3 and backgrounds, specifically this one dealing with patterns and a pattern gallery.

These may not work depending upon how new your browser is. See the note about browser compatibility on the pattern gallery.

So naturally I wanted to combine them both into a pure CSS version of the Cicada pattern:

And since it is is all generated with css there are no images and you could get fancier with the colors, gradients, and opacities if you want.

Here is an example of one that takes a single base color (#026873) and adds highlights to it:

Here is the css:

You can see the full examples in the gist.

Posted on 7 Jul 2011