Improving the AngularJS app starter template

Kim T
Creative Technology Concepts & Code
5 min readAug 19, 2014
AngularJS combined with Twitter Bootstrap

AngularJS is a very powerful front-end library which allows you to build apps and prototypes quickly, without getting bogged down in browser inconsistencies. However when you look at the documentation and examples you will find that they vary massively and there are several ways to write, organise and build an app.

I’ve built a few projects using AngularJS & Twitter Bootstrap, and have now settled on a structure which feels easy to maintain and understand. I will attempt to explain it here with examples.


The main requirements of my starter app are:

  • Setup Guide, how to get started etc
  • Libraries, AngularJS for functionality & Twitter Bootstrap for grid/layout/styling
  • File & Folder Structure, grouped by functionality into modules
  • Example App, showing common features: load list, filter, sort, load single item, edit, save
  • Task Runner, automate common processes
  • Documentation, auto generated from the code
  • Automated Tests, for the future
  • Fully responsive
  • Style guide

And hopefully it will look something like this!

Setup guide

A README.md file in the root of the site which is compatible with GitHub’s readme format. It explains the technologies used, how to install and run the commands, the file/folder structure and the contact information for support. I’ve included some lines of the readme here as an example:

angular-bootstrap
===========
AngularJS and Twitter bootstrap combined
AngularJS `http://angularjs.org/`
Twitter bootstrap `http://getbootstrap.com/`

## Installation and running tasks

Install [node.js](http://nodejs.org/) then navigate to the site root within terminal and type:

npm install

Once the node modules have installed you should now have access to run the task runner. In your terminal you should be able to use the following commands:

gulp docs
gulp test
gulp watch

Libraries

For the example we need to include the libraries the example is based on. My example uses the following libraries:

  • angular.min.js — the core angular library (107KB)
  • angular-resource.min.js — optional resource library for requests (3KB)
  • angular-ui-bootstrap.min.js — angular ui for twitter bootstrap components (64KB)
  • angular-ui-router.min.js — optional router for nested views and other things (20KB)
  • bootstrap.min.css — and the twitter bootstrap css library (110KB)
  • glyphicons-halflings-regular.ttf — the vector scalable font icons (40KB)

File & Folder Structure

The file and folder structure is important to get right from the start. This prevents developers getting confused and putting the wrong code in the wrong places, which eventually reduces efficiency. Another key part to the structure is organising the modules by functionality (item, list, overlay) instead of type (css, js, html)

app/             --> all of the files to be used in production
data/ --> json data files
index.html --> app layout file (the main html template file of the app)
libs/ --> external libraries and fonts
modules/ --> modules grouped by functionality
app/ --> main application module
app.css
app.html
app.js
item/ --> view/edit item
item.css
item.html
item.js
item-new/ --> new item
item-new.css
item-new.html
item-new.js
items/ --> list of items
items.css
items.html
items.js
overlay/ --> popup overlay
overlay.css
overlay.html
overlay.js
gulpfile.js --> task runner settings
package.json --> node.js module settings
README.md --> Setup guide
test/ --> test source files and libraries
e2e/ --> end-to-end test runner (open in your browser to run)
unit/ --> unit level specs/tests

Example App

For this to all work we need an example app which shows off this structure. As part of the app i’ve added some common features needed including:

  • Login
  • List of items (sortable, filtered, custom date ranges, pagination)
  • Single item view (requests REST api, tabbed view with view and edit states)
  • New item form (filling out data in steps, datepicker, submit to server)
  • User profile in overlay
  • Custom timecode inputs (testing different ways of entering/displaying data)

You can view this all working here:

Task Runner

For the task runner i’m using Node.js with Gulp to watch and run tasks via the command line. All the settings are contained within the gulpfile.js which includes:

  • gulp test — run automated test using karma and jasmine
  • gulp docs — auto generate the documentation form the code using jsdoc
  • gulp watch — watch all javascript files for changes, when a change occurs it runs gulp test

Documentation

After running the gulp docs command, the documentation is generated into a docs folder in the root of the site. This can then be viewed using any web browser. The documentation plugin used is called jsdoc. Which requires comments to be written in the following format:

/**
* @file Item
* @summary Item module
*/

/*globals window, angular, document */

Automated Tests

After running the gulp test command it will scan any tests in the test folder and output results into the command line. Here is an example of a test for an angular module:

/**
* Test
**/

/*globals jasmine, describe, beforeEach, afterEach, module, it, inject, expect */

describe('Controllers.Submissions', function () {
'use strict';

beforeEach(function () {
module('Services.Login');
module('Services.Submission');
module('Services.URL');
module('Controllers.Submissions');
});

describe('SubCtrl', function () {
var scope,
controller,
http;

beforeEach(inject(function ($rootScope, $controller, $injector) {
$rootScope.url = '/';
$rootScope.urlExt = '';
scope = $rootScope.$new();
controller = $controller('SubCtrl', {$scope: scope});
http = $injector.get('$httpBackend');
}));

afterEach(function () {
http.verifyNoOutstandingExpectation();
http.verifyNoOutstandingRequest();
});

it('should have fetchSubData', function () {
expect(scope.fetchSubData).toBeDefined();
expect(scope.fetchSubData.loadingInd).toBeDefined();
expect(scope.fetchSubData.loadingInd).toEqual(false);
});

it('should have getUsers', function () {
var feed = { response: 'example' };
expect(scope.getUsers).toBeDefined();
http.expectGET('/submissionusers?searchstring=joe');
http.whenGET('/submissionusers?searchstring=joe').respond(feed);
scope.getUsers('joe').then(function (data) {
expect(data).toEqual(feed);
});
http.flush();
});
});
});

Fully Responsive

For this feature we are using Twitter Bootstrap which makes it extremely easy to create a grid that responds to any browser/screen size. You can also re-order rows and columns to keep inportant information at the top of the screen. In the example app we have a sidebar which jumps to the top when on mobile:

<div class="row">
<div class="col-md-4 col-md-push-8">
<p>This is the sidebar on desktop, but at the top on mobile</p>
</div>
<div class="col-md-8 col-md-pull-4">
<p>This is the main list of items</p>
</div>
</div>

We could write this part ourselves, but as we are using the form, dropdowns and input styling from bootstrap it makes sense to embrace it fully!

Style Guide

The last feature for our web app is a dynamic style guide, which contains all the elements used across the app. This page is useful to check consistency of design across UI elements and ensure there are no bugs when put together. For my style guide i’ve used a Twitter Bootstrap template and modified it to include Angular and some custom elements here:
http://kmturley.github.io/angular-bootstrap/app/style-guide.html

So there we have it, a fully working app built using AngularJS and Twitter Bootstrap, structured into modules, with documentation, automated tests and a guide.

You can view the source project here:

And view the working app here:

--

--

Kim T
Creative Technology Concepts & Code

Creative Technologist, coder, music producer, and bike fanatic. I find creative uses for technology.