Improving the AngularJS app starter template

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:


No comments:

Post a Comment