Monday, November 30, 2015

Ionic and AngularJS

In my personal time, I have one mobile app that I manage: BattleTech Calculator. It's a calculator for an old 1980s board-and-dice game, makes a lot of the tedious math move more quickly so we can focus on pretending to blow up our giant robots.

I went with Framework7 for this one, on grounds that it looked like a winner. It's HTML/CSS with some DOM manipulation capability similar to jQuery. It has basic routing, doesn't look half bad. And BTC being a non-work app, I figured there's no harm if Framework7 turned out not to work out well.

Trouble With Framework7


Ultimately, it did not work out well.

First was the freezing/crashing issues. I thought it was just my phone because the other two folks didn't have any problem... until they reported that they did. Just switching between tabs in the usual fashion, it would freeze solid and you'd have to terminate the app and start over.

Second was a reported visual rendering bug. I could never replicate it myself, but I got several reports in the Store after one update, that when they switch tabs the old tab's content would be visible on top of the new tab's content. Again, I couldn't make it happen but the reports were consistent enough that, combined with the freezing, I decided to try something new.

And that's not including some documentation inaccuracies, the $$ and $ bug, and a few other quirks and shortcomings.

Ionic Framework is based on AngularJS, and on the web side of things that's a totally new thing for me. As I described in prior blog posts searching for a HTML framework, Angular is designed around concepts like modules and components, instead of the designer-driven daily-spec-change chaos which typifies a lot of our web-map applications. But in this case, I did have a solid idea of what I wanted, and even a working prototype in my old version.

It took some getting used to... but Ionic/Angular kinda rocks.

DOM manipulation and AngularJS


DOM manipulation is out the window. Because of data-binding on the form widgets, the ng-show and ng-hide directives allow other stuff to show and hide as the form is manipulated, allow for recalculations to happen any time the form is changed, etc. The result is more intelligent form widgets and less code and code repetition.

Old, a separate piece of logic to show only the applicable table:
var which = $(this).val();
$('#tab-meleehitlocation span.meleetype').hide();
$('#tab-meleehitlocation span.meleetype-'+which).show();

New, the table is intelligent as to its visibility condition:
<div ng-show="viewdata.meleetype == 'punch'"> Lorem Ipsum </div>

Old, remove the highlight from all rows, add to this one:
$('#tab-meleehitlocation span.meleetype-punch div.row').removeClass('hit').filter('[data-roll="'+rolled+'"]').addClass('hit');

New, the row knows when it should be highlighted:
<div class="row" ng-class="{ highlighted:viewdata.outcome == 2}">
This data-binding and implicit state awareness is a key point of what makes AngularJS what it is, but felt very foreign and difficult to wrap my head around at first. But once it sunk in... I'm impressed. I think that AngularJS's "state propagation intelligence" could achieve any sort of unpredictable DOM manipulation we could need, in a more intelligible fashion than our old jQuery implementations.


Ionic Framework and Ionic View


Ionic Platform itself is a set of tools based on Cordova/Phonegap, but adding their special sauce of CSS utility classes, button colors, a set of icons, etc. And yet, I was allowed to ignore and override to suit a few specific needs, e.g. a SVG dice icon, in lieu of FontAwesome which did work just fine.

So as far as the HTML/CSS flexibility, Ionic really did work well here.

And then there's Ionic View, Ionic's test-deployment platform. It's similar in theory to the Phonegap Developer App:
  • Your testers download the Ionic View app and sign in to the Ionic View service, and see a list of app which they have been invited to test;
  • You type ionic upload to upload your content to the Ionic View servers;
  • Testers re-sync your app, and re-launch and test. No code signing, OSX builds, etc.
This significantly accelerated my testing cycle, even as one single person on a weekend project. The uploads are as fast as Xcode compiling it and far faster than dropping the APKs onto Google Drive and waiting for them to sync. And since it's over data (meaning, while I'm at home, over wifi) I can test it as I walk around, refill my coffee, etc. without ADB pitching a fit and forgetting to reconnect the device, etc.

So yeah, Ionic's non-Angular nature... also a winner.


What It Means For BattleTech Calculator

The new version of BTC isn't finished yet; I have one whole panel to go. But let's look at bits of logic and overall code volume, and see what Ionic has helped me to improve.

https://github.com/gregallensworth/BattleTechCalculator/tree/master/www
https://github.com/gregallensworth/BattleTechCalculator-Old/tree/master/www

  • The very large HTML is broken into partial views. This keeps me visually focused, which is great if you have "situational ADD" aka being interrupted all the time.
  • HTML volume is currently 609 lines compared to 1125 lines. Add another 125 for the last page, and this is still a 40% reduction.
  • JavaScript code volume is 295 lines (not counting that unfinished panel, maybe 150 more) compared to 522. This would be a mere 20% reduction... but still 100 fewer lines of code. This is largely due to the removal of DOM-fussing since AngularJS takes care of that automagically.
  • Almost every line of code is simply more readable: default settings are declared in the controller instead of as checked attributes, code is more logical since it doesn't read from fields and do the DOm shuffling.
  • The code is even easier on the eyes, since $('#') is absent.
  • The app runs very smoothly for the most part, under Ionic View, on my old Galaxy S3. Smoother than with Framework7.
  • The app hasn't crashed once yet, in a few days of development and testing. This counts for a lot!

What it Means For Work


Virtually all of our work is websites, and the designers use mobile-unfriendly layouts with floating panels and the like. So Ionic won't be doing a lot there; it can scrape by for websites, but support for IE isn't so hot. But for the few mobile apps we do each year, we have a winner.

For websites, I am starting to get into the feel of AngularJS. If we can combine this with something visual like Bootstrap, it could be very neat. The big challenge there, of course, is that our clients and designers don't have Bootstrap on the brain so we end up rewriting large parts of the visuals anyway. But for a general system of DOM management and data management, AngularJS is looking pretty sweet, and I'll be working with it some more on personal projects.