Wednesday, April 30, 2014

Living in AngularJS for a few months

What is it like for a Java / Objective C / Mobile guy to live in Angular for a few months? It has been an interesting ride for sure.

The mobile work, which I dearly miss, is at a stand still while marketing decides on various issues such as it being free or having a price. This means I need to help out in other coding areas and for right now. They decided to toss me into AngularJS.

It takes some time to get your head wrapped around Angular. What is a service, controller, directive or manager? How does this magical binding work? Where is the GET call for the REST service?

I was using the 30 day trial of WebStorm as that seemed to be the tool of choice for every video I watched doing a demo of Angular code. I like the IntelliJ product line. I use AppCode for iOS work and Android Studio for by Android projects. We get a multiple user site license of IntelliJ which includes the WebStorm plug-ins so I switched to that. WebStorm 8.0 EAP has better Angular integration which will be merged into IntelliJ at some point. For my personal use I am waiting on the next IntelliJ sale to pick up a copy for home use.

Using IntelliJ allows me to run our Java based application server too. That code is a Maven project making it easy to import as an IntelliJ project. Nice having one IDE for both of those projects and I especially like the Dracula theme. I run a dark theme in Eclipse but it has some minor UI issues.

IntelliJ ties in to our JSHint settings as well. The Jenkins integrated build system will kick out the project as failing to build if you don't follow our JSHint settings. Having the IDE show them to you as errors before you run the GRUNT process is very nice.

Using GRUNT SERVE allows me to start the web process and then have any changes I make to the HTML, CSS, SCSS or JS files automatically built and pushed out to the web. I am using Chrome which also integrates with IntelliJ for JavaScript debugging. I also use the integrated Chrome web developer tools but the IntelliJ debugger is more feature rich to track down the harder issues.

I run GRUNT before I set up a STASH pull request. That runs JSHint, Unit Tests, Minification and all the other fun which is the same process Jenkins runs. I try to always check in clean code.

How is Angular? It appears to be a really solid API with a lot of helpful features. The live data binding is one of them. You set up {{ variable_name }} in the HTML and if that variable is defined in the controller the HTML will automatically update when you change the variable value in your JavaScript. There is also all sorts of boolean logic you can apply to show and hide HTML elements using ng-??? tags.

Angular is like Android in a number of ways. You need to understand 3 or 4 objects before any one thing works. In Android you would need to know the Activity houses a Fragment and they are both using a layout defined in XML that pulls data from strings.xml and the List in the Fragment is using another java class that uses one or more other XML layouts to display the data. Very confusing at first. Angular has a similar tie in of controllers, HTML layouts, CSS styles, etc.

I did not write the initial version of the Angular app. I got to wade into the deep end with a list of bugs and feature requests to see how much damage I could do. Took a few weeks to start knowing where to look and the initial project did not follow the best file naming conventions, which has since been cleaned up.

Now I have a pretty good idea of what is possible, what bootstrap widgets are available, how to look up and use underscore.js helper methods, available moment.js methods and how to get around the other 3rd party code bits we pull in via BOWER.

Of course general programming knowledge always applies. There are loops and IF statements and all that fun. It was basically learning a new framework. The fun comes in when you get to test in various browsers. So far the Angular side has not caused any issues but HTML and CSS play a different ballgame. I am on a Mac as I do iOS programming. Things were working fine in Chrome, where I spend most of my time. The UXD staff uses FireFox and ran into various minor issues that I was able to quickly fix. I also test in Safari and have not had to do anything special in there yet.

The real fun begins in Internet Explorer. I have a VM set up with Windows 7. Things were not looking so good in there. Turns out we have some bad HTML which the other browsers ignored. Specifically an extra end tag of
. IE gave me a non-helpful error message deep in the bowls of Angular for that. The other browsers just blew it off. Simple fix. The other changes were setting some bonus CSS styles for the modals - commonly called dialogs in other frameworks. All the changes I made did not affect the other browsers so I was not required to put IF statements around them just for IE.
I went ahead and set up a pretty full environment in the Windows VM which included GIT, GRUNT, Ruby, BOWER, NPM, Node.JS and Sublime text editor. I did not set up IntelliJ on that side as I would have to kill it on the Mac side and start it on the PC side each time. I am generally making small changes for IE so that has not been a big deal.

The web tools in IE are not as full featured as FireFox or Chrome but are servicable. I was able to change CSS styles live and see the effects which is very happy. CSS seems to be a lot of trial and error to get things right. Not a big fan of that mode of development. When I see something out of place in my Android layout XML I generally know why it is messed up and I can quickly fix it. With CSS the whole team plays the "throw stuff at it until it works" approach. Try setting margin, now set DIV to overflow = auto; or toss in a float: left. When it works I am happy but I always want to know why that made it work. Plus the CSS has a lot of inheritance which is not obvious when the styles are defined in multiple CSS or SCSS files. At least the web tools in the browsers will show you where various things came from and what overrides what.

We plan on turning most of the HTML and CSS manipulation over to the CSS team. I believe they will do a better job laying things out in the CSS files getting more object reuse there and they can keep track of how changes will affect various areas on different screens. They won't touch the binding areas or the i18n areas.

Like most of the projects I have worked on we have done the i18n work and have had the project localized into Spanish and Korean. A member of the sales staff plans on doing a French localization for us when the code is closer to complete. I always put strings into separate resources just in case someone wants to localize the product.

For QA to test this we generally hijack a rarely used locale and do a simple reverse English version of our test. That way QA can quickly see on any screen if the text is not reversed then we have not pulling it from the resource but they can still read everything on screen. Reading backwards is tricky but sure is a lot easier than guessing at a language you don't know at all.

I wrote a small Java utility to reverse the strings for this file. Big deal right? Reverse a string, grade school 101 that task. The issue is you don't want to reverse macro replacement text. The string "You have {{carrot_count}} carrots\nBuy more!" is reversed to "!erom yuB\nstorrac {{carrot_count}} evah uoY".  Don't want \n to be n\ and the variable name cannot change.

In the end I am not minding my time in Angular but would really like to get back into mobile. Anytime you learn a new framework it opens your toolbox even if it to steal ideas on how to do things differently in your "old language and framework". The Angular app is not large but it looks good and is very functional. It beats the heck out of the previous JQuery app I helped out on.

What don't I care for? JavaScript is not statically typed so a number of programming errors don't appear until you run the project in a browser. IntelliJ does its best to keep you honest but it can't catch everything. Misspelling a variable in HTML that is bound to a JSON field will burn you more than once. Dynamic variables of this type, that type, array or not at different times will also burn you. It also causes havoc with the intellisense / autocomplete features of the IDE. You end up keeping multiple files open just so you can reference variable names. Refactoring is a lot tougher too.

The worst part is browser differences. Sure, in Android land you deal with different SDK versions and screen sizes. Under iOS you have a couple of different screen sizes and some hardware differences. Here I sit on a single computer and I have to test in 4 browsers minimum. It appears IE is the pickiest of the bunch so I should start in there but it has the least useful web tools and I would be working in the Windows VM all day long which does not add to the fun factor.

Like every new program language and framework it has been an experience. Some good, some bad, some fascinating. I will steal as many ideas as possible from this experience when I get back into mobile land.