The Frontend

In Part I of this series we already described our RESTful backend built upon Java 8 and Spring. This part will cover our first client application built with AngularJS.

We use trackr to keep track of our working times, travel expenses and vacation requests. Thus we need a couple of basic administration interfaces for all entities as well as the high-level input forms. Also we wanted to extend the security defined in the backend into our frontend - if the REST service prohibits users to view or edit an entity these actions should not be visible to them.

As testing and automatization are a large part of our Java backend we wanted to have these features in the frontend as well. Apart from a testing framework and a test runner this means some kind of build and dependency management. All of this should be a part of our Gradle build.


I’ll start with Bower for the dependency management. While it’s fairly straightforward and simple to use we have ongoing problems with Bower because it fails the build. At one time a git command just fails, another time I was unable to delete some cache folder. I really hope they improve on this in the future. Everytime I change or add a dependency my Gradle build is prone to fail.

Another very specific problem was the jQuery dependency. There’s jquery and then there is jQuery in the Bower repositories. Bootstrap requires jquery. ut Bower randomly downloads jQuery or jquery, depending on… well, I don’t know. Since the folder structure is not the same this failed the build and the applicaiton wouldn’t run. It’s probably related to this issue. Now I don’t want to complain too much, maybe it was justified, maybe not; but it broke my build, and a dependency management system that is meant to be used for production purposes must not break builds.

Yet another problem, which isn’t Bower’s fault but came up when using it, is people adding incorrect packages. For one package the build folder was empty and only the project’s source code was included. We ended up using the master branch and not a release version to use this dependency.

Now with Maven’s dependency management I never had any of these problems. You add a dependency, Maven downloads it and it works. Bower needs more development in my opinion.


We are using Grunt for three tasks. Running JSHin, building production files out of our source code (minifying etc) and executing tests. Grunt worked really fine. The only problem could have been the configuration of the tasks when the documentation was insufficient. But most tasks have a good documentation and/or an example configuration file that describes all options.

Running Bower and Grunt From Within Gradle

You might already have seen this task from our build.gradle in the previous post.

task gruntTest(type: Exec) {
    workingDir 'src/main/webapp/WEB-INF/app'
    executable = 'grunt'
    args = ['test']

We have a few tasks like this that only execute commands such as grunt test, npm install and so on. I really like it, another developer checking out the project (and having all tools installed of course) just needs to run ./gradlew build and has a working WAR file (given all the node tools are installed).

The Architecture

We wanted the frontend to be very modular so we can extend it with other applications. This means we actually wanted to build a platform on which trackr is merely the first application. AngularJS already comes with support for modules. Furthermore we used RequireJS for Javascript dependencies. This allows modules to be integrated in the platform with very few changes. As a result our directory structure looks like this:

Folder Structure

Here is some example code showing how the application is loaded.

/* app.js */
define(['angular', 'modules/shared/shared', 'modules/module1/module1', 'modules/module2/module2', function(angular) {
    var app = angular.module('app', 'shared', 'module1', 'module2');
    angular.element(document).ready(function() {
        angular.bootstrap(document, ['app']); //If there's setup needed before the app runs.

/* modules/module1/module1.js */
define(['angular'], function(angular) {
   var module1 = angular.module('module1', []);
   //add controllers loaded by require, define routes, states etc.
   return module1;

Instead of the standard AngularJS routing via the $routeProvider we used with its $stateProvider. It allows nested states and views of the application which is really helpful for a modular approach. Every module can define its own states with its own URL prefix that doesn’t need to be rewritten everywhere.

Here is a small excerpt from our administration module’s state configuration.

       .state('trackr.administration', {
           url: '/administration',
           views: {
               'center@': {
                   templateUrl: 'src/modules/trackr/administration/administration.tpl.html'
           needsAuthority: 'ROLE_SUPERVISOR'
       .state('trackr.administration.projects', {
           url: '/projects',
           views: {
               'center@': {
                   templateUrl: 'src/modules/trackr/administration/projects/list.tpl.html',
                   controller: 'trackr.administration.controllers.projects.list'
           needsAuthority: 'ROLE_SUPERVISOR'
       .state('trackr.administration.projects.edit', {
           url: '/{id:[\\w\\.]+}',
           views: {
               'project': {
                   templateUrl: 'src/modules/trackr/administration/projects/edit.tpl.html',
                   controller: 'trackr.administration.controllers.projects.edit'
           needsAuthority: 'ROLE_SUPERVISOR'

This defines three nested states. The last one, trackr.administration.projects.edit will only populate one view inside the parents template and be accessible under the URL (/trackr)/administration/projects/projectId.


That’s what it looks like in action. You can also see the module selection on the left side. The layout is in an early stage from when I was mainly developing the features.

The RequireJS approach can put a lot of text at the top of your Javascript files, especially if the directory structure grows more complex. At first, I found this annoying, but then I took a look at a typical Java class. You probably don’t recognize them anymore because your IDE hides them and, what’s even more likely, you don’t write them yourself, but they are there: the import statements. It’s not so much different after all, with the difference that RequireJS imports don’t have any help from the IDE.

Our build will append and minify all Javascript files and to speed up loading in our production environment.


Restangular is a AngularJS module that hides the $http interaction with a REST service. Instead of building URLs by string manipulation you can use a fluent API, chaining methods together. Here is an example from our employee-editing controller.

var employeeBase ='employees', $;

employeeBase.get().then(function(employee) {
    $scope.employee = employee;'credentials').get().then(function(credentials) { /* do something with credentials */ });

$scope.deleteEmployee = function() {
    employeeBase.remove().then(function() { /* redirect to some other page */ });

As you can see it works with promises just like $http. It’s really intuitive and works quite well with Spring Data REST. Only the mapping of list results had to be configured in Restangular to match the Spring Data REST approach.


We used angular-translate to provide internationalization. It’s pretty straight forward, in most use cases you use the translate filter. Translations can either be served asynchronously or can be hardcoded.

        <th translate="VACATION_REQUEST.START_DATE"></th>
        <th translate="VACATION_REQUEST.END_DATE"></th>
        <th translate="VACATION_REQUEST.NUMBER_OF_DAYS"></th>
        <th translate="VACATION_REQUEST.STATUE"></th>
        <th translate="ACTIONS.ACTIONS"></th>

Edit: As Pascal Precht pointed out in the comments it’s better to use the directive instead of the filter whenever possible. The filter can have a negative affect on the perfomance. The code example has been altered to use the directive.


The backend implements a very strict security approach. Every user of trackr has a role assigned and the REST service handles the associated permissions. Now, in the frontend the user has access to all the code. I guess we could deliver different applications for employees and admins but that seems like too much overhead. After all the frontend does not contain secret code, it’s only the data that must and in the end will be protected by the backend.

Nonetheless, we don’t want users to see links to pages they could not access or to be able to edit an entity they can see but the for example a PUT request will be rejected. So I added additional security checks in some places.

  • State switching. A state can require a role to be accessed. Currently, if the user does not have the required role nothing will happen, but an error page is completely possible. (You can see this in the code for the $stateProvider above).
  • A has-authority directive to hide elements. This can be used e.g. to hide the link to administration in the top menu for employees.
  • We use a click-to-edit approach instead of forms. The directive for that takes the role of the user into account, too.

If used correctly this should be enough to display only allowed content to users of trackr. If users want to act maliciously they surely will be able to switch to some disallowed state, but eventually the REST backend will stop them from accessing the data.

Here is an example of the has-authority directive:

<ul class="nav navbar-nav">
    <li ui-sref-active="active"><a href ui-sref="trackr.employee">PAGES.EMPLOYEE.TITLE</a></li>
    <li ui-sref-active="active" has-authority="ROLE_SUPERVISOR"><a href ui-sref="trackr.supervisor">PAGES.SUPERVISOR.TITLE</a></li>
    <li ui-sref-active="active" has-authority="ROLE_SUPERVISOR"><a href ui-sref="trackr.administration">PAGES.ADMINISTRATION.TITLE</a></li>


Our backend has a pretty good test coverage. While I have written some smaller AngularJS applications I’ve never really set up tests for them, so this was rather new to me. I decided to use Karma as a test runner and Jasmine as a testing framework. Setting up Karma to work with RequireJS managed files was a task that required some time and research.

After being able to write and execute tests, the next questions were: How to test an AngularJS application, what to test and how to write code that is testable.

Let’s start with the first question. AngularJS provides angular-mocks to simulate a real AngularJS environment for tests. It allows you to boot an app, use injection in the test and mock the $http calls.

define(['angular-mocks', 'app'], function() {
    describe('some test', function() {
        beforeEach(inject(function($httpBackend) {
        it('should do something', inject(function($httpBackend) { ... }));

This is just an example and no real test. Soon it became clear I would have to do certain tasks in each and every test, like booting the app. Since I found no way to write some kind of test base class I thought of a different way to do this. It proved to be incredibly useful to have RequireJS on board. I just wrote a file that returns a function which will execute all basic test setup. In a real test I just have to require the file, execute the function and my test will be set up. I did this to boot the app and mock the $httpBackend with some data.

The next thing was: What do I test? I’m still not completely clear on this. I started with some very basic tests that just check if some $scope variables are defined. My idea was that this prohibits someone from deleting a $scope variable that still might be needed. Then I started tests checking if HTTP requests are executed when they should be; angular-mocks helps here. That’s mostly it. I don’t have very much business code so it’s mainly integration tests.

Overlapping was the question on how to write testable code. It’s easy to access the $scope in a test so it could be an idea to attach everything to the $scope and test it from there. But this breaks encapsulation. Sometimes you have a helper function in a controller that shouldn’t be on the $scope. So I used this pattern:

/* controller.js */
angular.controller(['$scope', function($scope) {
    var controller = this; = function(bar) {
        //do stuff

    $scope.baz = function() {'baz');

/* controllerSpec.js */
describe('controller', function() {
    var controller;
    beforeEach(function() { /* set up controller and app */ });
    it('should foo', function() {
        var foo ='bar');

I guess time will show us how to improve our actual tests, but a good base setup was found.

Code Coverage

IntelliJ IDEA has a great code coverage tool that I can run with the Java tests. This is also possible for Javascript. I used Istanbul by Yahoo with the karma-coverage task. It didn’t require any special kind of setup (just activate it and configure an output directory for the report). I discovered it rather late and it was a good eye opener how bad my coverage was. After one day of writing more tests I went from this

JS Tests Before

to this

JS Tests After

So I still need a good way to test directives, but it does look good for the time being. Istanbul even creates a page for each Javascript file that includes indicators which line, branch and function was covered.



The combination of RequireJS and AngularJS modules allows a really modular application which is very nice. Restangular integrated very well with our Spring backend. Karma, Jasmine and angular-mocks (and some RequireJS, too) helped in setting up a test environment which has many convenient helpers and lets you focus on the actual tests.

I didn’t so much like the experience with Bower as I have described. A tool that breaks my build without apparent reason is pretty bad.

Feel free to share your experiences with us in the comments.