This is an update to my previous article which talked about integrating AngularJS with Cordova. We'll go over how the process has changed with newer version of Cordova(3.4) and Yeoman(1.1.2). You do not really have to read the old article to make use of this one. A lot of the work we did previously was to 'massage' the Yo/Angular application structure to fit in a Cordova based application. This new approach is vastly simpler and easier to maintain.

Dependencies and Other Boring Stuff

Again, I will assume you have working knowledge of getting a simple Cordova application up and running on either Android or iOS. I will be using Android during the example, but there is no platform specific code involved, so substituting 'android' with 'ios' during the Cordova steps should work just fine.

Below is the list of versions for the installed artificats:

  • npm 1.3.15
  • cordova 3.4
  • yo 1.1.2
  • generator-angular 0.7.1
  • grunt-cli 0.1.11

The general idea of the following setup is that we have our Angular application, and our Cordova application, as two separate projects. The Cordova application will link to the Angular application at build time to pull in all the resources. The source structures need not step on each other, and can live in their own directories. There is a very thin wrapper around the Angular bootstrap process that will let us use Cordova plugins and features worry free from inside the Angular world.

To Action!

First we need to setup our Angular application through yo, just like we normally would:

mkdir c3a
cd c3a;
yo angular;  #accept all the defaults
#in order for grunt to pass I had to run the following first:
npm install karma-jasmine --save-dev;
npm install karma-chrome-launcher --save-dev;
#now you should be able to run

Now it's time to setup our cordova app:

cordova create c3c --link-to=c3a/app  #KEY ARGUMENT --link-to
cd c3c
cordova platform add android

Thats it (kind of)! You now should be able to run your simple Cordova+Angular app on a device of your choosing.

Of course we are not really 'integrated' with Cordova as all we have right now is a fancy HTML application run in an embedded browser on a device, not terribly useful! Lets get talking to the device, shall we?

Bootstrapping Anuglar

This all takes your code in the Angular application, the Cordova side of things does not need to change at all. First, I like to have an empty placeholder 'cordova.js' at the root level. This file will get replaced by the cordova build process, but if you run your app in a browser for testing you at least won't get false 404 errors for it.

Next, we need a hook into cordova. We'll replace Angular's normal boot process by not using the ng-app directive, instead we'll manually bootstrap it.

'use strict';

var CordovaInit = function() {

	var onDeviceReady = function() {

	var receivedEvent = function(event) {
		console.log('Start event received, bootstrapping application setup.');
		angular.bootstrap($('body'), ['c3aApp']);

	this.bindEvents = function() {
		document.addEventListener('deviceready', onDeviceReady, false);

	//If cordova is present, wait for it to initialize, otherwise just try to
	//bootstrap the application.
	if (window.cordova !== undefined) {
		console.log('Cordova found, wating for device.');
	} else {
		console.log('Cordova not found, booting application');

$(function() {
	new CordovaInit();

There really is not much to go through here. We initialize a listener for the 'deviceready' event if Cordova is available, and as soon as we get that we bootstrap our Angular application. The advantage to that is that from within or Angular code we know that any device specific items will be available without us having to check or wait on any other Cordova related events.

Job done!

A few small items are still left un-done, but should be considered. The biggest is that when development is done the 'dist' directory of your Angular application should be used. With that though, you will want check that you don't 'cdn-ize' the links to your third party libraries if you want the application to run offline.

A full working example can be found at github: