I\'m writing a PhoneGap/Cordova app with Ionic, and using SQLite (with ngCordova) for persistent storage. The core of the app is a scrolling list of items which are retrieved fr
Managed to get it working in the end. Posting this here for anyone else having the issue.
dataFactory.js
openDB
>> dropTable_
>> createTable_
etc). Also returned a promise (empty)Returned initDB
and getAllItems()
from the factory immediately
.factory('dataFactory', [function($window, $log, $q, $cordovaSQLite, dummyDataGenerator){
var db_;
// private methods - all return promises
var openDB_ = function(dbName){
var q = $q.defer();
// ...call async SQL methods
return q.promise;
};
var createTable_ = function(){
var q = $q.defer();
// ...call async SQL methods
return q.promise;
};
// ...etc
// public methods
var initDB = function(){
var q = $q.defer();
// successively call private methods, chaining to next with .then()
openDB_("myDB").then(function(db){
var schema = "...SQL schema here..."
dropTable_(db, "FirstTable", schema).then(function(tableName){
// ...etc
// when all done, resolve the promise
q.resolve();
})
})
return q.promise;
}
var getAllItems = function(){
var q = $q.defer();
// ...call async SQL methods
return q.promise;
};
return {
initDB: initDB,
getAllItems: getAllItems
};
]}); // <-- factory
app.js
resolve
ability of ui-routerresolve
to the top-level abstract state to fire off the call to initDB
initDB
to the child state's resolve
objectInject the resolve object into the controller
// APP ROUTING (using ui-router) .config(function($stateProvider, $urlRouterProvider){
$stateProvider
// top-level abstract state that houses Ionic side menu & nav
.state('app', {
url: '/app',
abstract: true,
templateUrl: "templates/sideMenu.html",
resolve: {
dbReady: function($log, dataFactory){
// (1) init the DB
return dataFactory.initDB().then(function(){
$log.log("initDB promise resolved");
});
}
}
})
// the following states are all child states of app
.state('app.items', {
url: "/items",
views: {
menuContent: {
templateUrl: "templates/gbCaseList.html",
// (3) now we can inject the items promise into our controller
controller: function($scope, $log, items){
// (4) uses resolved items variable injected by ui-router
$scope.allItems = items;
}
}
},
resolve: {
// (2) note that we MUST inject the dbReady promise, if we don't this will instantiate immediately
items: function(dbReady, $log, dataFactory){
// the following call returns a promise
return dataFactory.getItems();
}
}
})
All working now. Massive thanks to this post for clearing up my use of ui-router Run controllers only after initialization is complete in AngularJS