AngularJS and PlantLink

If you’ve ever had a houseplant die on you, pay attention. Eight months ago, my company, Heavy Code, started a gig with a local startup, Oso Technologies. I’d heard of this company months earlier when their Kickstarter campaign hit the news. They were building a product that would notify you when a plant in your house or garden needed more water. It’s called PlantLink and one day, they needed help with their AngularJS web app.

The Concept

PlantLink Basestation and LinkThe promise of PlantLink is simple. Stick the sensor in your potted plant or lawn and get notified when that plants needs water even if you’re not home.

In this case, the basestation plugs into your wired network. Then, via Zigbee, it communicates with all of the links in your house to gather soil moisture readings. It sends all that moisture data up into the cloud for processing and that’s where Heavy Code comes in.

The Code

When we came aboard the project, we inherited an existing AngularJS codebase. It took care of some of the more difficult parts such as the authentication, but was a bit messy and woefully incomplete. Given that the API was a moving target, the flexibility that JavaScript and AngularJS offers allows us to easily make changes to the front-end without worrying about all any cruft or ceremony with other JavaScript libraries.

Performance

Performance of the app is an ongoing concern. We’re constantly looking for more ways to improve performance. Using webpagetest.org to test our speed, we’re able to see that the app loads everything needed in 1.8 seconds and in under 500K. This isn’t just the DOM Loaded event. This is the complete load time — everything is ready for user input at that point in under 2 seconds.

PlantLink dashboard page speed

Unlike old school web apps, this initial load includes the entirety of the application code, which weighs in at 200K (not gzipped). So, when we switch from view to view, the only additional network traffic is loading HTML partial views and accompanying resources. The good news is that we still have room for improvement as it’s not likely that the entire application code is needed at the start of the app.

Challenges

Of course, not everything is smooth sailing. Like any other piece of software, this web app had challenges to build.

Browser Compatibility

One huge pain point is browser compatibility. Early on, we decided that we wouldn’t support IE8 and near the end we opted to remove IE9 support as well. Beyond those browsers, many of the modern browsers are fairly consistent, but for some CSS3 features like flexbox, there’s a lot of room for error. For flexbox in particular, browsers are at different points in their implementation. Chrome and IE11 support it without any vendor prefixes, but Safari still requires prefixes. To help deal with those inconsistencies, we utilize a CSS post-processor, autoprefixer, and connect it to our grunt process.

The “Angular Way”

If you’ve spent anytime looking at AngularJS, you’ll see someone use this phrase. There were times we wanted to use a community plug-in, but many plug-ins assume that you’re using jQuery in a “classic” sense. While we do include a reference to jQuery (to augment the jqLite included with AngularJS), you can’t just use a jQuery plugin in an AngularJS controller and call it a day. No, the place for jQuery is in a directive — this is the Angular Way.

So, when we wanted to use a plug-in, we also had to hope that someone in the community had built an Angular directive to use with that plug-in. While this was usually true, those directives typically were made to utilize the entire plug-in. We often use only a small piece of the plug-in and the result is code bloat. When you’re building a responsive web app, minimizing the amount of JavaScript is of paramount concern.

Images

For this app, we use SVG wherever possible to maintain crisp images regardless of the screen’s resolution or pixel density. The whole @2x movement of providing multiple images is a nightmare, so we avoid it wherever possible. Most of the SVG images in PlantLink are background images where they can be easily placed, sized, and constrained.

A Mobile Helping Hand

Midway through development, Chrome released to its Canary product a mobile device emulator (it has since been moved into the main Chrome release).

Chrome Devtools Mobile Emulator

This handy devtools feature allows you to get a general idea how the app is going to look on a mobile browser. I say “generally” because all it really does is change the size of the windows and pixel density. It doesn’t actually emulate those browsers, so things may look different on Chrome’s mobile device emulator than on the actual device. For this reason I recommend having a “device lab” where you can manually test out a device in your hand.

The Result

See for yourself over at dashboard.myplantlink.com. Then go buy yourself a PlantLink system and keep those plants alive.

PlantLink Dashboard Full Screen

 

PlantLink mobile screenshot

Is AngularJS for you?

Should you use AngularJS on your next project? Without hesitation, yes. If you’re crazy and are still trying to support old versions of Internet Explorer, you’re gonna have a hard time. Angular provides some guidance on old versions of IE, but once Angular upgrades to 2.0, old IE support will disappear.

AngularJS lets you move quickly stay flexible. In my experience I can get to a working web app much quicker with AngularJS than ever before. It’s my not-so-secret secret weapon to build solid, fast, and responsive web apps.