An Angular 2 app from inception to production

At Inspire, we are building ways for you to gain useful and actionable insights about your home. We’re creating tools to enable you to see how your home is performing and give you recommendations for areas to improve your sustainability footprint, optimize your efficiency, and increase your home value.

The idea for this app has evolved over the years. At the end of last year it finally gained enough momentum that we decided to build it. Instead of the end-of-year slump, we used December and early January to focus on getting an MVP of the product idea out the door.

In this article, I’ll share some of our learnings from a technology perspective.

Starting from scratch

Staring at a blank codebase can sometimes be daunting. This being my first Angular 2 app, I chose to bootstrap it using Yeoman, specifically the recipe from FountainJS. It was good for getting going quickly, and also good to determine which tools the community is gathering around. If I was to start a new app, now knowing more of the mechanics of the underlying build tools, I would probably start from a more vanilla base. You can learn about new tools and design patterns, but you can also end up with extra unused code from the generator. 8/10 would use as an accelerator again.

Project structure

Aside from build tools, another piece of the project that Yeoman determined for us was the folder/file structure. We refactored this along the way, and have plans to refactor further.

Right now here’s a loose structure:

/src
— index.html -main entry point)
— index.ts -main imports)
— /app
— — index.ts -confusingly duplicate name, ngModule, main App Module
— /components
— /layouts
— — shared layout, header/footer
— /modals
— — only use popups when absolutely necessary
— — our component html & ts files…
— /pipes
— — our custom pipes -TitleCase!
— /services
— — our api services
— /assets
— — beautiful images from our amazing design team

TypeScript

When I played around with A2 last year, I initially rebelled against TypeScript. I had gotten burned in the past with CoffeeScript, and I didn’t immediately see the upside being greater than the downside of the learning curve and tooling changes. However, after working with it throughout the project, I am fully on the TypeScript hypetrain. :train: There are quite a few benefits to working with TypeScript, but my top two are in-editor highlighting and Class/API introspection. When you enable your Sublime/Atom plugins, you feel like you’re wired in like Tony Stark. You feel safe, like Jarvis has your back. Simple typing typos surface immediately. When you’re working with external libraries, as one tends to do in NPM-land, TypeScript really shines. You can see what every method expects and returns, and objects become less generic and more useful. TypeScript: making you fitter, happier, more productive, comfortable, not drinking too much…

Constant Refactoring

When developing this app, we were moving fast and light. Weekly sprints meant we had to quickly spin up pages and their underlying components. So we started with getting the functionality working, then refactored as it meant sense.
 
HTTP in Components

There wasn’t a ton of documentation on the HTTP libraries in Angular quite yet, so we used our common sense to get from simple to full-featured. First order was to put the http calls in the component. Using Observables, we could subscribe to the response, and bind that to a component output.

HTTP in shared service

The second step to HTTP enlightenment was to move some of these shared HTTP calls to a service, just to avoid duplicating the code across subscriptions. But we were still initiating the calls from the components, and each time a component loaded we were making a new call to the API. There was a bit more we could do. 
 
HTTP in model with subscriptions
The third and final step towards the light was to create full blown models. These models contain classes which mimic the data structure returned from the API. They also implement BehaviorSubjects, which allow components to subscribe to the data, and the models can initiate a refresh from the API whenever appropriate.

Hosting

Perhaps our most unique, if not controversial technology choice. We wanted to ship quickly, and we knew S3 had static website hosting. We didn’t need a full featured web server with server-side redirection or server-side rendering — just something to serve up Plain Old HTML CSS JS and image assets. A throwback to the early 90s, if you will. The one speedbump that we did encounter was with our URLs. Two requirements: First, we wanted to be able to deeplink into the app. We didn’t want to just enter the app through one point. Second, we wanted it to have a clean url structure: /foo, /bar, etc. No Angular 1 /#/. S3 Hosting, however, needs a small bit of configuration to work. First we redirect any unknown paths to the root with the /#/ appended. Then, in our root component, we strip out the /#/ and send the route on its way.


router.events.subscribe(s => {
if (s instanceof NavigationEnd)
let params = new URLSearchParams(s.url.split(‘/#/’)[1]);
if (params.rawParams != “”) {
console.log(“hashroute found. redirecting to:”)
this.router.navigateByUrl(“/” + params.rawParams)
}
}
});


Measurement and Analytics

Our goal from day one was to measure all the things.

We already had infrastructure in place, namely SegmentIO and Google Analytics. We like Segment because it gives us the ability to spin new services up in the future very easily. 
We use page tracking which is hooked into our Angular router to track time on page and bounce rate. We use event tracking to track more specific events like when users are clicking on specific elements Here’s an example:

this.angulartics2.eventTrack.next({ action: ‘set_user_cost’, properties: { category: ‘op_costs’, label: this.homeCost.cost_type }});

Everything flows well into Segment then into GA and we’re able to do our usage analysis in GA. Success.

Conclusions

After completing our MVP, my opinion on Angular 2 is: 9/10 would Angular 2 again. There isn’t a ton of documentation, but the official docs are fairly good. Definitely would recommend learning to love TypeScript, it makes working with official and unofficial libraries clearer, and makes you a safer developer. Always be Coding, but also: Always Be Refactoring. S3 does work for Angular 2, and it’s fast. Segment + Google Analytics + Angulartics = Super Trackability. Overall, it supports a pleasant developer experience. I would recommend Angular2, and I will definitely be jumping back into it for future projects.

Like what you read? Give Matt Anderson a round of applause.

From a quick cheer to a standing ovation, clap to show how much you enjoyed this story.