TL;DR: This article outlines how to manually bootstrap Cordova/AngularJS applications after the deviceready event to prevent Cordova plugin race condition errors.
AngularJS is an extremely popular Single Page Application Framework maintained by Google. Given it’s popularity, it’s no surprise that developers often choose to use AngularJS as their Framework of choice when building a Hybrid Application using Cordova or Phonegap. To get the most out of this pairing, careful steps should be taken when using Cordova and AngularJS together, particularly when dealing with Cordova plugins.
deviceready event provided by Cordova within our applications.
There are several ways we can go about using Cordova Plugins with AngularJS:
- Do Nothing - If our application isn’t invoking Cordova Plugins during startup, we might avoid this race condition altogether. However, this approach is sloppy, and errors may manifest later as the application grows.
- Safety check each call - Alternatively, we can wrap each Cordova Plugin call using a wrapper that ensures the
devicereadyevent has been fired. We could configure a Factory to listen for the
devicereadyevent and then chain promises, as seen below. While this works, it still increases the overall complexity of our application by requiring each of the developers to remember to safety check each plugin call.
- Manually Bootstrap Application - Lastly, we can opt to launch our AngularJS application after the
devicereadyevent. With this approach, by the time our AngularJS Application code is running all of our Cordova plugin APIs are safe to execute. Manual bootstrapping allows us to maintain cleaner code at the potential cost of delaying the startup of our application.
In this article we’ll demonstrate one approach to manually bootstrapping a Cordova/AngularJS application. To do this, we’ll discuss automatic and manual bootstrapping of AngularJS applications and show an example Cordova application using AngularJS, ngCordova and cordova-plugin-geolocation.
The most common way to initialize an AngularJS application is by using the ng-app directive:
The ng-app directive performs automatic bootstrapping of an AngularJS application and initializes the root module of the application if one is specified (in this case, myApp). The ng-app directive also indicates the root element of the AngularJS application - any AngularJS template code or directives found within the root element will be evaluated by AngularJS during the application bootstrapping process.
In order to start our AngularJS application after the
Note: Only use one bootstrap method for an AngularJS application. If using angular.bootstrap, do not include an ng-app directive and vice versa.
Using the AngularJS Bootstrap function, we can now initialize our AngularJS application in the
deviceready event listener callback function:
You can see this approach demonstrated in the sample AngularJS/Cordova application detailed in the subsequent sections.
Our sample Cordova/AngularJS application consists of one view that displays Geolocation Data in a Bootstrap Panel.
The application itself consists of three main files:
index.html - Contains a single AngularJS view using ng-controller to provide context data.
app.js - Declares our AngularJS Module and defines the ApplicationController.
deviceready event, the application will launch if run outside of the Cordova environment, which may be useful for live reload tools or debugging.
Our example uses the following dependencies for this example, managed via bower:
- Cordova (5.4.1)
- AngularJS (1.5.5)
- ngCordova (0.1.26-alpha)
- Bootstrap (3.3.6)
- jQuery (2.2.3)
We also be used the
cordova-plugin-dialogs plugins in conjunction with ngCordova.
For this example we created a default Cordova application with the CLI and installed the above dependencies using Bower. We then installed the specified Cordova plugins using the CLI.
You can check out the complete code on github.
Manually bootstrapping your AngularJS application after the deviceready event is just one method of avoiding potential race conditions when using Cordova plugins in AngularJS.
Do you have different ways of handling Cordova Plugins and AngularJS? Post them below!