Taking JavaScript Seriously in Grails (AngularJS and CoffeeScript)

  Whenever I write JavaScript I throw all software craftsmanship discipline out the window. There are no unit tests and very little structure to the code. It's just me and the browser refresh button until we get it right. If you are lucky you may have jQuery to provide a nice CSS selector based api that somewhat shields you from browser quirks. Maybe you even kept your project from devolving to the point where every page is basically its own JavaScript app with no hope of reuse between them. Even then JavaScript is still likely a second class language in your project. Surprisingly, this state of affairs is normal. I want to take my client side scripting just as seriously as any other code in my Grails web app. I want tests, structure, and less boilerplate, and I am going to use AngularJS and CoffeeScript to do that.
  I started with a new Grails 2.1 app and implemented the excellent AngularJS tutorial on top of it. Once I got it working I turned all the JavaScript code into CoffeeScript. Overall these technologies work very nicely together. Of course there were a few tricks I learned along the way and I will point those out. Grails and AngularJS are both MVC web frameworks that make heavy use of dependency injection and have great support for testing. There is some overlap that I will discuss later, but for the most part Grails stays on the server side and AngularJS stays on the client side. AngularJS actually feels like a more Grailsy way to handle the view layer than what Grails provides out of the box.

  The Grails side of this is pretty standard. I've used the handy resources plugin to manage my client side static resources like images, js, and css files. It allows you to define dependencies between these resources and then bring the required ones into a page just by specifying the top level of the hierarchy. There is a Grails Controller (shown below) with two kinds of actions. There are pass through actions (list and show) that defer to AngularJS, and end points for restful calls (query). PhoneService is a Grails service that handles the actual data. In a real application it would be backed by a proper data store, but here I hardcoded the actual JSON from the AngularJS tutorial.

  Though there is an AngularJS plugin for Grails, I didn't see any reason to use it. The Grails resources plugin makes using AngularJS so simple, and I like having direct control over which version of AngularJS I use and where the files are put.
  Much like Grails, AngularJS has its own set of controllers (for page manipulation), services (for general purpose tasks), and dependency injection to tie everything together. The DI feels a lot like Groovy with the way that injection takes place by name automatically. If you look deeper it starts to look a lot like Guice. Below are the Angular controllers used in this application to get JSON data and binding it to the page via $scope.

  There is much more to say about AngularJS, but before I do I'd like to mention that the AngularJS code that I am showing has been converted to CoffeeScript. I find CoffeeScript to be much more pleasant to use that JavaScript (and more Groovy like). The conversion was relatively straight forward, but there were a few gotchas around scoping of variables due to CoffeeScript's lexical scopes and implicit function safety wrapper. As you can see in the above example it is necessary to prefix controllers with an @ to elevate their scope. Also my AngularJS service test shown below uses a 'setup' variable to give the tests access to objects created in the 'beforeEach' section.
  I used the Grails CoffeScript plugin for this, but it was an older version that I found useful. There is a handy way that one can configure arbitrary CoffeeScript files to be converted to JavaScript. I liked this approach because I was content to let the same mechanism convert my CoffeeScript tests that is converting the rest of my CoffeeScript code. The newer version of the plugin doesn't seem capable of this. Being new to CoffeeScript, I also appreciated seeing the generated JavaScript.

Grails and AngularJS Together
  There are limitless ways that you could combine Grails and AngularJS. By posting this I hope to gain some new insights. I favor Grails quite a bit here just because I am more comfortable with Groovy. Think of this example as a Grails app which delegates to an AngularJS sidecar specializing in putting the final touches on the view layer.

Grails vs AngularJS responsibilities
URL mapping for full page transitionsclient side data binding and dom manipulation (single page changes)
provides RESTful servicesmakes the AJAX calls
application concerns (overall file layout, server and client side dependencies, building and packaging, control center for all commands)JavaScript organization and separation of concerns
server side DI with Springclient side AngularJS DI
server side unit, integration and overall functional tests with SpockJavaScript unit testing with Jasmine

  Rather than use AngularJS routing, I let Grails handle it (mostly because I am more familiar with Grails). You can see in PhoneController above that the pass through actions act very much like AngularJS routes. They map a url to a template (by Grails convention) and an AngularJS controller (by passing an explicit value to the template). In this case the template is a Grails .gsp.
  Grails and AngularJS share the templates which in this case are .gsp files. There are two passes to transform these files now. First Grails compiles the .gsp on the server and applies tag libraries, then AngularJS applies it's bindings and directives on the client. This is where AngularJS shines and I let it do most of the work. One thing to remember is that since Grails encodes the output of tag libraries, you can't use the AngularJS binding inside them. For example...

  Getting Grails and AngularJS to communicate effectively is simple once you realize that Grails params and AngularJS $scope are both the state that the respective controllers care about. So I found a way to stamp the Grails controller's params onto the AngularJS controller's $scope using ng-init. The main.gsp is a layout that I apply to all my Grails .gsp files. It is basically a place to put common elements that will appear on every page. You can see how I am taking this opportunity to always set the ng-controller (which was specified by name in the Grails controller) and pass the Grails params into it with ng-init.

  AngularJS provides resources for making rest calls. This is a great way to communicate with the Grails backend. To remove a lot of boilerplate code I created a service that constructs resources based on Grails URL conventions. You can see in the AngularJS controllers above where I make use of the service named 'Grails' to get phone data. The code for this service is below. It simply substitutes Grails controller, action and id values for their placeholder in the url. It will default to values found in $scope (which were copied from the Grails params if you remember).

Unit Tests
  Grails itself offers great support for writing tests, especially with the 2.0+ enhancements that allow better Spock integration. I must say that testing my code with Spock is bliss with its concise syntax, built in mocking, and intuitive assertions.
  The thing about AngularJS that really got my attention is the promise that I can be in a similarly happy place when writing JavaScript tests. And it delivers! This is no doubt because there are test gurus behind AngularJS. Jasmine allows my unit tests to have a familiar structure coming from Spock. The DI that is core to AngularJS allows me to isolate my logic and mock what I need to. The tests are run by js-test-driver which needs to connect to a browser. Your web app doesn't have to be running, js-test-driver just uses the browser as an engine to execute the javascript (and you can execute in multiple browsers in parallel). There is an IntelliJ plugin for js-test-driver that lets me run my tests as if they are JUnit. There is even JUnit output that I can use in Jenkins. And surprisingly code coverage for JavaScript (but I lost this when I converted to CoffeeScript). It was trivial to create a unit test for my AngularJS service described above that makes rest calls to Grails. I merely instantiate the service, mock the backend, and assert that the right calls would be made based on the scope and overrides.

Functional Tests
  Functional tests run against your app externally, usually through some type of browser automation. AngularJS provides end-to-end testing to accomplish this. These tests are described with Jasmine just like AngularJS unit tests. They are executed in the browser and are blazingly fast. AngularJS e2e tests are awesome, but I used a Grails based solution instead.
   Geb is a Groovy way to automate a browser and it works well with Spock to write Grails functional tests. It's basically a Groovy DSL on top of Selenium/WebDriver. Even though it is not as fast as AngularJS e2e tests, I am more familiar with these tools and I like the page object pattern that Geb uses to separate browser automation in the test from the specific markup of the page.

Above you can see the definition of a page. Most of the CSS selectors that address page elements can go here. Aside from avoiding repetition of these selectors, it makes the tests less brittle. When there are changes to the markup you just make a corresponding change to your page definition and all your tests still pass. There's no need to change the test itself unless the behavior of your test conceptually changes.
  Below you can see the related test. The setup method navigates to the specific page and the tests use the page object definitions to manipulate and make assertions about the page. Note how I am able to pass 'phoneThumb' an index so that I can click arbitrary thumbnail images. I think this makes for very readable and robust tests. Converting the AngularJS e2e tests from the tutorial to Geb was very intuitive.

  Running the Geb tests was not so straight forward. There is a Geb plugin for Grails that does some basic setup of Geb inside of Grails, and there is tighter integration to be had by following this tip from the Geb author. The plugin allows you to run the tests from the Grails command line, but I had to resort to a bit of a hack to run the tests from my IDE. Basically I needed a way to configure Geb outside of the Grails app.
  Speaking of Geb configuration, I have a few observations about my choice of driver. I tried HtmlUnitDriver, FirefoxDriver and ChromeDriver. HtmlUnitDriver just didn't work for my tests. FirefoxDriver worked out of the box, but was slow. ChromeDriver was fast (much closer to AngularJS e2e speeds) but there is a minimal amount of setup to be done on your machine first.

  AngularJS brings a lot of the same good things to my client code that Grails brings to my server side code (structure, DI, tests). CoffeeScript makes my client code look and feel more like Groovy (less boilerplate, many common idioms). Overall my client side scripting is now a first class citizen and sits right beside the rest of my code (literally and figuratively).

  All the code is on Gtihub. Feel free to use this as a starting point and send pull requests when you figure out improvements.


  • Run in jenkins build on headless server and capture test failures (bonus points for code coverage)
  • Use Testacular rather than js-test-driver to run unit tests.
  • Replace CSS and HTML with Less and Jade respectively.
  • Full CRUD with RESTful Grails endpoints.


pjagielski said...

Nice post!

My only doubt is the mixing gsp with Angular templating - a bit of meta-programming In Angular scaffolding plugin Rod Fletcher separated pure html Angular templates, what do you think of that? On the other side - in your model eg. Spring Security tags can be used...

Steve said...

Same feedback as pjagielski on the mixing of template solutions. I went with Angular routing and reduced Grails to only talking JSON - complete separation of concerns.

Corinne Krych said...

same comment, for html5-mobile-scaffolding plugin, i'm planning to integrate Angular, but no GSP.

Steve said...

Genius post! Very insightful and well paced. Thanks!

Bhushan said...


Thanks for the post. It will be awesome if you can add some action to post content to Grails from AngularJS. I am also wondering, how is security handled? In case we use spring security for our grails app.

mahasiswa teladan said...

hi...Im student from Informatics engineering nice article,
thanks for sharing :)

John Michle said...

Its really good to know about that, some facts and other points given here are quite considerable and to the point as well also the complete procedure given is also of most importance, would be better to knew about more of them.

Hvac Service Management Software

Rob said...

Nice article. I feel CoffeeScript is the language du jour for client MVC.

I think most devs can relate to the 'throwing all standards out the window' with Javascript, but a framework doesn't fix that problem for you - all your JavaScript should be unit testable and cleanly separated regardless. Angular just provides some conventions to teach this to people.

Ronan Mullarkey said...

Brilliant article! Really useful.

shafin kothia said...

it was Informative Post,and Knowledgable also.Good Ones

sharepoint training institute in hyderabad

msbi training institute in hyderabad

Ranska said...

hi Clay thank's for this article,
I'm currently writing https://github.com/ranska/rang https://github.com/ranska/aether who is a little lib focus on coffee script class layer for angular. I try to find people who can tell me if there is thing's they like, want to be add or remove from it.
Could you please give me your point of view on it.

Raju Kumar said...

I am extremely impressed with your writing skills and also with the layout on your blog
Angularjs Training In Hyderabad

sss lokesh said...

This is the best way to upgrade our skill set thankyou.....
Angularjs online Training

Roshini RS said...

This technical post helps me to improve my skills set, thanks for this wonder article I expect your upcoming blog, so keep sharing...
Angularjs training in chennai|Node JS training|Angularjs training center in Chennai

Steve Smith said...

Great work.Angular supports event driven programming. Angular makes web browser smarter. It decouples DOM manipulation from application logic. This improves the testability of the code.

AngularJS Training
AngularJS Training in Chennai
AngularJS Course in Chennai
AngularJS Course
Online AngularJs Training

osvaldo anderson said...

There are tutorials that is specially designed to help you learn AngularJS as quickly and efficiently as possible.

Priya said...

Angularjs is a structural framework for developing the dynamic web applications. Angular's data binding and dependecy injection is capable of eliminating much of the code.
angularjs training in chennai |
angularjs training chennai

Priya said...

Nodejs is an open source and cross platform environment for developing the server side web application. The main advantage of using nodejs is because of its fastness, single threaded and highly scalable.
Node JS training in chennai | Node JS training institute in chennai

Scaffolding Machines said...
This comment has been removed by the author.
Scaffolding Machines said...
This comment has been removed by the author.
Scaffolding Machines said...

Jayati Tools Private Limited is a trusted company which is Manufacturer and Supplier of scaffolding tools all over the world. We are manufactur the Scaffolding Accessories, Scaffolding tools, scaffolding socket, Tuff Scaffolding Machine and all types of Scaffolding equipments, System Scaffmarking machine. http://www.scaffoldingmachines.com/

Mani OBS said...

Thanks a lot for sharing this amazing knowledge with us. This site is fantastic. I always find great knowledge from it.
Hire Angular JS Developer

mary Brown said...

JavaScript Training in Chennai | Ecmascript 6 Training in Chennai | ES6 Training in Chennai | Angular 2 Training in Chennai | Yeoman Training | D3 Training | ReactJS Training | Gulp Training

Kits Online Training said...

nice blog, thanks for sharing
Dataguard Online Training Institute

Best Etl Testing Online Training

Best Oracle Golden Gate Online Training institute from india

Best Vmware Online Training institute from Hyderabad india

ashraf ashu said...

I would like to see each release announced on this blog, your way of explaining is very nice I have gone through custom directives in Angular Js online training I had spent several days to get the hang of Angular JS was successful .

angular online training in hyderabad
angular online training

Adlearning Technologies said...

Thank You for sharing your article. I like it. We provide TIBCO Online Training in Hyderabad.

onlinetrainings expert said...
This comment has been removed by the author.
vinayangadi said...

Thanks for sharing this valuable information to our vision. You have posted a trustworthy blog keep sharing.Nice article I was really impressed by seeing this article

Asp .net Training In Bangalore

Webtrackker Noida said...

Webtrackker technology is the best IT training institute in NCR. Webtrackker provide training on all latest technology such as AngularJS training. Webtrackker is not only training institute but also it also provide best IT solution to his client. Webtrackker provide training by experienced and working in the industry on same technology.Webtrackker Technology C-67 Sector-63 Noida 8802820025

AngularJS Training Institute In indirapuram

AngularJS Training Institute In Noida

AngularJS Training Institute In Ghaziabad

AngularJS Training Institute In Vaishali

AngularJS Training Institute In Vasundhara

AngularJS Training Institute In Delhi South Ex

Gopi Krishna said...

AngularJS is a toolset for building the framework most suited to your application development. It is fully extensible and works well with other libraries. Every feature can be modified or replaced to suit your unique development workflow and feature needs. Read on to find out how.

AngularJS Training in Chennai
AngularJS Training Institute in Chennai

AngularJS Certification Training in Chennai

AngularJS Corporate Training
AngularJS Online Training

Jones Sathya said...

Come and read us!! We are moving our blog into a new site with a much more pretentious goal. We are going to teach how to be AngularJS Ninjas!!! That's right! We have taken a couple of weeks to prepare our first workshop, absolutely free!!!!

AngularJS Training in Chennai
AngularJS Training Institute in Chennai

AngularJS Certification Training in Chennai