Angular, TypeScript, and Promises! Oh my!


With all the buzz around Angular 2.0 and ES6/ES2015, I figured I may as well start moving that direction. There seems to be some consensus that writing your Angular 1.x apps in TypeScript is a good first step, and should theoretically ease the migration path.

At first migrating my Angular code to TypeScript wasn't a big deal. Add types to variables, functions, etc: check. Use TypeScript modules instead of IIFEs: check. Move registration of classes with Angular to the bottom because classes don't hoist: check. Dig into services and try and get types set correctly for $http promises: @#$@)@#$)@!!!

Perhaps for folks who have lived with strongly typed languages most of their career, it's pretty straight forward. For someone like me who hasn't had much to do with strongly typed languages in over ten years, something just wasn't clicking. There also doesn't seem to be a whole lot out there that walks a noob like me through typing a promise. Here is my contribution to the topic.

If you're using or learning TypeScript, you should have heard about type definition files already. If you haven't, most of this post will probably go over your head. You should at least familiarize yourself with TypeScript with the TypeScript Tutorial and/or the TypeScript Handbook. You could also give John Papa's TypeScript Fundamentals a shot.

All of the types you will need are in the angular.d.ts file you can get from Definately Typed. What tripped me up was figuring out which types to apply where and how to make the generics line up in such a way that the compiler was happy. Let's start with an interface definition for a service method that is going to make our $http request.

module foo {
    export interface IThingsService {
        allTheThings(): ng.IPromise<any>;

So here we have a method that returns a promise. the ng.IPromise type is the type that has definitions for then, catch, and finally. I don't usually recommend using the success and fail shortcut methods. If you're happy using success and fail then you'll need ng.IHttpPromise instead.

You'll notice I've used any as the type ultimately returned by my method call. any? Isn't that a cop out? any can certainly be a cop out, but it's in TypeScript for a reason. For now, trust me that is what your type needs to be. I'll explain in a minute.

Now, let's take a stab at an implementation.

module foo {
    class ThingsService implements IThingsService{
        static $inject = ['$http','$q'];
            private $http: ng.IHttpService,
            private $q: ng.IQService

        allTheThings(): ng.IPromise<any> {
            return this.$http.get('')
                .then((response: ng.IHttpPromiseCallbackArg<IThings[]>): IThings[] => {
                      var things: Things[];
                      things =;
                      return things;

OK. There's a lot there, so lets go over it. First, note the types for $http and $q. It's not strictly necessary that they be there, but this is TypeScript. You may as well get used to typing everything. That is the point, right? Plus, you'll get typing hinting for $http and $q if your editor/IDE understands type definition files. If you're searching the net for Angular + Typescript + Promises, I assume you're far enough into TypeScript + Angular to recognize dependency injection and TypeScript's shorthand for defining class properties. I must admit, I didn't like that shorthand at first, but it's growing on me.

Let's take a look at the types in the callback definition.

(response: ng.IHttpPromiseCallbackArg<IThings[]>)

Our single parameter named response should look familiar to anyone used to $http promises and then. The type we use is ng.IHttPromiseCallbackArg. This gets us type hinting for the properties on the response object like data, status, headers, etc. The generic type is the type you expect the data attribute to be. If you have an interface defined for the response data, go ahead and use it here. If not, then use any. You have to specify some kind of type there.

Next we define the return type of our anonymous function. IThings[] Now is when we can get specific about the type of data the promise will contain: our array of Things. The TypeScript compiler is happy because we specified a type of any for our service method call. But if I specfied a specific type for my then callback, why don't I just specify that type for the method call itself? Ah. Here is where the fun begins. Let's modify our method a bit.

allTheThings(): ng.IPromise<any> {
    return this.$http.get('')
        .then((response: ng.IHttpPromiseCallbackArg<IThings[]>): IThings[] => {
              var things: Things[];
              things =;
              return things;
        .catch((response: ng.IHttpPromiseCallbackArg<any>): HttpException => {
                var boom: HttpException;
                boom = {
                    code: response.code,
                    message: response.statusText
                return this.$q.reject(boom);

Now we've added a catch method. I don't have an interface defined for error responses so I've left the callback function parameter type as any. Notice that I'm going to return a custom error object from my catch. This is why we specified any on our service method call. Regardless of what you do inside your catch, it's unlikely that you're going to be returning an array of Things. This will make the TypeScript compiler very unhappy if you have specfied that your service method will be returning a promise containing an array of Things. If you're not going to use catch in this context and rely on a promise farther up the chain to deal with errors then, yes, you can use a more specfic type in the service method definition. Maybe your catch is going to return an empty array of Things. That would work.

One more thing before I wrap up this way too long post. Let's look at the consumer of this service call.

    .then((data: Things[]): void => {
        this.things = data;
    .catch((error: HttpException): void => {
        this.things = [];

Notice that our function parameter for then and catch are the types we returned from our service call. If you think about it, that makes sense. That's what promises do. It's worth noting that we haven't lost much in terms of typing by using any on our service allTheThings method. The values returned to then and catch are typed so we know what to expect.

Hopefully this will help someone else trying to wrangle types with $http requests, TypeScript, and Angular.

What Ever Happened to Dojo?


I was listening to one of the JavaScript podcasts I listen to—Adventures in Angular, I think—where the conversation had turned to ES6, transpiling and the tools around that process. Apparently webpack is the new shiny. Rolling my eyes at still one more tool to try and come up to speed on, I went to the web site to check it out. As I read over the introduction page in the docs, I thought, "This reminds me a lot of Dojo's build process. This is hardly new. Whatever happened to Dojo anyway?"

Back in 2010, I was hired to be the primary developer for small on-line university start up. I hadn't really worked on a project of that scale before. One of the first questions I asked myself was, "How am I going to manage the jQuery code?" I started googling strategies for architecting and managing large numbers of third party and custom jQuery plugins. Generally, all I found was "Well...". There were a few suggestions, but they felt a bit forced and didn't really give me the warm fuzzies.

The more I searched for a solution that spoke to me, the more I found people saying, "If this is really a concern, you should consider using Dojo Toolkit." So I did consider it. Backbone had just barely been released. People didn't have opinions about it, so it wasn't something I wanted to take a risk on. There was no such thing as Angular (2014) or Ember (2013). In then end I went with Dojo and I really enjoyed working with it. One of the features I really liked was the ability to build modules and only load what I needed for any given page. However, as often happens with start ups the money ran dry and I was looking for a job again in 2012.

I haven't touched Dojo since. My next job was happy with jQuery. Nowadays, no one talks about it. Whenever someone talks about JavaScript frameworks, the canonical list is Backbone, Angular, and Ember. Not necessarily in that order. Maybe I'm reading the wrong web sites. Maybe I'm listening to the wrong podcasts. I don't know. Dojo never was on the tip of everyone's tongue. I don't think they have ever tried to be the new shiny. They first released in 2007, so that ship has kind of sailed anyway. They do talk a lot about wanting to be a rock solid platform that large undertakings can build on. So if stability and longevity are a primary concern for a project you are currently planning, Dojo might be worth a look.

ES6 & Black Magic


So I've been dipping my toes in ES6 and have come across this bit of code:

((diameter) => diameter * 3.14159265)(2)

Part of me thinks that's kinda cool. Part of me thinks, "What crazy black magic is this?!? Burn the witch!!"

I seem to remember a trend where the goal was to make programming languages more like human languange. So have we given up in favor of something more succinct? Let's be honest. Human language is a mess. How many prepositions does one need, really? I suppose it ends up depending on context. We also have code libraries that look like this:


Some of it undoubtedly has to do with advances in technology. How well do you think Angular would have run on a 486? Some of it has to relate to the level of sophistication of today's web developer. I don't have a degree in computer science. I took some CS classes in high school and college and that's about it. On the other hand, I have been tinkering with programming since I was a kid. (Anyone else remember the TRS-80?) ES6 is not your father's JavaScript. (Yes, I'm old enough to say crap like that. Refer to previous reference to TRS-80.) We've come a long way from DHTML and I think the changes coming in ES6 reflect that.

The Endless Debate: Mac vs Windows


Let me start out by saying I develop on Windows. No, I'm not a .NET developer. I started out in Java, did LAMP for a while and have been working on becoming more proficient on the frontend of late. I've been around long enough that there were no laptops when I started developing. No Ubuntu. No Mint. Unix was a server platform. Period. Mac was still Macintosh was rarely used outside of graphic design/desktop publishing and video editing. I seem to remember the odd person writing code on a Macintosh that didn't have something to do with Adobe or Avid, but they were extreme outliers. I don't remember anyone developing web sites on a Unix platform, but I'm sure they were out there. The only Unix guys I knew were either dev ops guys writing shell scripts or C++ developers writing desktop applications for Solaris or Irix.

Here we are 15+ years later. Laptops are ubiquitous. Macintosh is now Mac and is actually a fairly common web development platform. You see job postings all the time where one of the perks of employment is being provided with a Mac. Because obviously everyone wants to be working a Mac, right?

I work for a consultancy these days. My first day at my current gig, I was handed a Mac and told, "We use Macs here." Uhhh. OK. Six months later what is my opinion of the Mac as a development platform? Meh. There's no magic sauce that makes Mac some wonderous user experience. Indeed after a few weeks working on a Mac, I was griping about my frustrations to one of the die hard Mac guys I used to work with. His response: "You're not drinking enough koolaid." Six months later, I'm still not in love. In the end, it boils down to this: It's all about what you're used to and how invested your are in making a change. I'm used to Windows and I'm not invested at all in changing to a Mac. I'll limp along when I'm required to and will breathe a sigh of relief when I can go back to my comfort zone.

Don't get me wrong. Windows has it's problems. You'll never hear me say otherwise. The thing is, so does the Mac. So does Linux. There is no perfect operating system. A Macbook does look sexy. I'll give you that, but that doesn't justify the premium price tag for me. I was listening to an episode on The Web Ahead today about the impact of the Apple watch. What struck me was the conversation about technology as fashion. They talked about how Apple is marketing the watch, not as a smart device, but as a fashion accessory. Because that's what watches are. Jenn's guest, Josh Clark, also talked about how kids are just as fashion conscious today as they were in his day, but today's kids care less about the logo on their shirt than they do the logo on their phone. Maybe that's Apple's secret. They've figured out that today technology is fashion and it's all about having the "right" logo on your laptop/phone/watch.

In some circles you're not a true developer unless you're on a Mac, particularly if you live primarily on the front end. Lately the guys on the Shop Talk Show have been pushing back against this monoculture that is developing. It's nice someone with a larger voice in the community is. At my last job we were all over the map. There were three guys on Ubuntu, one using Mint, two on Macs, and the rest of us were on Windows. Honestly, I think that is how it should be. Developers should be allowed to work on whatever platform makes them most efficient. If your tooling is platform dependent, you're doing it wrong.

Migrating Generic IMAP to Gmail Hell


I have a friend who is an attorney who keeps tons of email. He's been having issues with reliablilty on the shared hosting account he is on so I suggested we move him to Google Apps. Then I discovered he has nearly 15,000 email messages stored. A bit of a shocker, but it's Google. They have made migrating to Google Apps a breeze, right?


It has been a complete nightmare. We tried just dragging and dropping folders using his Apple Mail client. It was moving one message every three to five minutes. At that rate it would have taken just about one month to migrate all 15,000 messages.

So we tried Google's tools. Big mistake. The migration tool available on the apps dashboard pretends like it's working, but it doesn't. After 2.5 days, it reported having moved all his email except it didn't. It moved two out of eight folders and only about 8,000 of the 15,000 messages. Nice job, Google.

I called Google support—one of the perks of being a paying apps customer. They suggested I use a Windows desktop tool that is supposed to be better, but I couldn't make it work. It refused to accept his secret key and would bail without doing anything. Once, apparently randomly, it actually got past the secret key check, but then couldn't create any of the necessary labels and quit. I read and re-read all the support docs I could find, but could not find anything that explained why the secret key was being rejected. I tried calling support back, only to have the support rep read back to me the support pages I had already read through.

Next I tried talking to these guys on the advice of the one of the IT guys at work. Apparently we're using them for a big domain migration we're undergoing right now. Supposedly they are the best 3rd-party migration service out there. There's just one catch. Their software is licensed on a per person basis and you have to buy a minimum of 10 licenses. I contacted them and asked if their free trial would work to get one person migrated. They responded that I could buy a license for one person. Except that you can't. The web site won't let you buy fewer than 10. I tried chatting with someone on their web site to see if I was missing something. He told me the minimum was 25. Do they not even know how their own site operates? I contacted them by email again saying I couldn't see how to order just one license. I explained that I was happy to pay for one person, but I didn't want to pay for 10 if I only needed one. Their response? Nothing. So, if you're small potatoes, don't waste your time.

I had some PHP code lying around from a time in the past when I needed to migrate email from one server to another. I didn't use it then, but decided that was my next best option. Problem: it was apparently some seat-of-the-pants coding. It was mostly broken and got some things flat out wrong. So after several hours and much trial and error, I finally got it working. Seemed to work like a charm. The folder I was testing with had about 1200 messages in it and moved to Gmail in just a few minutes. New problem: in the message list view, all the dates were being displayed based on the date the messages were moved, not the date of the last message in the conversation. Even though you can specify an "internal date" in the PHP funciton call—which some seemed to think should do the trick—it wasn't working. Even with the date parameter set and properly formatted, Gmail kept right on displaying the date of the copy, not the date of the last message. To be clear, the actual dates on the message were not affected. You could open the message and see the correct date, but that's just annoying.

This morning, I started Googling for a solution to the date problem...ironic isn't it? Apparently this has been an issue for years. This thread was started in 2009. TL;DR: use Thunderbird. So after weeks of fussing with Google's migration tools, several support calls to Google, and a failed attempt to engage with a third party, I fired up Thunderbird, pointed it at both accounts and in less than a day I have all 15,000 messages moved to Gmail. Apparently not all IMAP clients are created equal. For whatever reason Thunderbird plays nicely with Gmail.

What really bugs me about this whole thing was the long, painful process. It wasn't until I tried to write my own code, ran into an issue with my code and started looking for a solution to that specific problem that I finally found a workable solution. Why, when I spoke to the first support rep at Google about migrating this enormous quanity of email, didn't he just say, "Hey, our tools suck. Just use Thunderbird. You'll be much happier."

Hopefully, some day in the future, someone else will be trying to migrate to Gmail and will find this post sooner rather than later in his or her process.