I’m totally convinced that the best way to learn anything is through having a hobby project. I’m so convinced about that, that I created a free 8-lesson YouTube course around that topic!

Well I’ve just finished “walking the talk” of that course - a 31 day streak of moving a hobby project forward from zero to basic features complete:

31 Day Streak To Get it Home

Learning Goals

I developed a small Angular 2 application, with a few very simple goals:

  • Learn about using Firebase for Backend Storage (essentially a serverless* application)
  • Create an app I actually need. In my case, that was an app to make use of my Pocket links when generating eNewsletter (in my case the Motivated Programmer newsletter. You should sign up!)
  • Build something substantial in Angular 2 and get a feel for whether I’d like it on larger apps.

So I birthed “PuppyMail” to scratch that itch.

The Rise of PuppyMail

Well PuppyMail delivered in spades on those three objectives. With the TL/DR being:

  • Firebase is all kinds of awesome. Particularly when coupled with AngularFire2.
  • I could deliver “Cradle to Grave” on all the basic features that I wanted in this app in 29 hours - or basically a month of hobby hacking every day.
  • Angular 2 all the things! I love this framework so much.

Show me the screenshots!

Ladies and Gentleman, I give you PuppyMail:

The PuppyMail Dashboard

And I thought I would go all out with a landing page to (with links to source, etc).

The Landing Page

What did you learn along the way?

Yes. Well. There were quite a few side tracks in those 31 days. But all wonderful learning experiences none the less.

A few things really did prove trickier than I anticipated.

1. GetPocket doesn’t support CORS

First “crash and burn” moment for me was lack of CORS support on the GetPocket API.

That meant the standard http angular component would die in the browser when doing the cross-origin calls. This lead to a tiny bit of glue in a node proxy which I called puppymail-server. Under the covers, it just uses express-http-proxy to do all the heavy lifting.

2. Custom Firebase tokens

I needed to generate Custom tokens for Firebase logins (since I wanted the user to be able to use their GetPocket creds as auth to the Database)

This was actually a blessing, since I already had the proxy server doing all the Pocket oAuth proxying, so it was easy to inject a custom Firebase token on the way back from a successful oAuth.

The Database Auth rules on Firebase are just fantastic. I can lock down sections of the Db to just the user that creates them. So very painless!

3. PrimeNG is so productive

Paginated lists turned out to be trivial. Just throw in a PrimeNG DataList component, point it at your array of objects, and you’re good to go. Rince and repeat for OrderList if you need to sort that list. Throw in a few Growl notifications, a couple of SplitButtons, and a pinch of Dialog action and you’re cooking.

I will definitely be recommending PrimeNG to enterprise clients as a great way to standardise the app experience.

4. SemanticUI makes so much sense

I’ve used Bootstrap a lot in the past, and SemanticUI really takes ideas to a whole new level of usability. The whole “semantic-ness” is just so readable! I love creating a <div class='stackable two column grid'>!

I need to get deeper in SemanticUI, and fortunately the docs are just awesome.

5. Deep Linking and Nginx

This one really caught me off guard in deployment. Nginx kept throwing 404s when deep linking into the app using html5 style URLs.

You’d end up with requests like: /puppymail/login/backFromPocket which you’d hope would route to the LoginController, but end up 404’ing as Nginx tried to resolve that to a real file. Apparently there are serverside fixes which map all 404’s back to index.html to support this. That’s on my list, but a quick workaround is using a HashMappingStrategy in the router on the client side.

This means you end up “hashy” style links like /puppymail/#/login/backFromPocket, but that doesn’t worry me for now - especially since it was a one-line change to my Angular module to:

imports: [RouterModule.forRoot(routes, { useHash: true })],

And I was done!

6. through 1000.

There were tons of other stuff I learned along the way about Angular 2 - particularly in creating re-usable components that shared data across the app. Still plenty to learn about Observables, RxJS and error handling. But the pieces are coming together for me.

I just can’t believe how fast the thing runs too! Just awesome!

Can’t wait for my next hobby project. I can feel some Ionic 2 mobile app action coming on to channel my Angular passion into the mobile space.

And in the meantime, if you are a GetPocket user, have a play with PuppyMail, or checkout the source code, or just sign up to the Motivated Programmer Newsletter.