title: Angular/Ionic and async SQLite - ensuring data factory initialised before return
body: <p>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 from the SQLite database. </p>
  
  <p><strong>listController.js</strong></p>
  
  <pre><code>.controller('ListCtrl', [
    '$scope',
    'dataFactory',
    function($scope, dataFactory) {
  
      var items = dataFactory.getAllItems().then(function(data){
        $scope.allItems = data;
      });
  
    }
  ]);
  </code></pre>
  
  <p><strong>dataFactory.js</strong></p>
  
  <pre><code>.factory('dataFactory', [function($window, $log, $q, $cordovaSQLite, dummyDataGenerator){    
  
    var db_;
  
    // ...lots of SQLite fun in here
    // cascading async callbacks to load the database and inject dummy data
    var openDB_ = function(){...};
    var createTable_ = function(){...};
    // etc
  
    var getAllItems = function(){
  
      var q = $q.defer();
      $cordovaSQLite.execute(db_, sqlSelectString, []).then(
        function(results) {
          $log.log("SQL SELECT successful");
          var i, len, allItems = [];
          for(i = 0, len = results.rows.length; i &lt; len; i++) {
            allItems.push(results.rows.item(i));
          }
          q.resolve(allItems);
        },
        function (err) {
          q.reject(err);
        }
      );
      return q.promise;
    };
  
    return { getAllItems: getAllItems };
  ]}); // &lt;-- factory
  </code></pre>
  
  <p>Initially I was returning the factory straight away. The controller did <code>getAllItems()</code> which ran before the data was ready. The view was initially empty, only showing anything on return to the route after a second <code>getAllItems()</code></p>
  
  <p>So I tried delaying the return of the factory by adding a factoryReady() function and only calling it once all the internal DB stuff was ready</p>
  
  <pre><code>var factoryReady = function(){
    return {
      getAllItems: getAllItems
    };
  };
  </code></pre>
  
  <p>And now there's an undefined error as the <em>entire</em> factory is unavailable when first called, rather than <code>getAllItems()</code> simply returning empty-handed. I can see that the SQL database is being correctly written to in due course, but Angular throws an exception before this has finished.</p>
  
  <p>I realise now that this is predictable,  I've read the post <a href="https://stackoverflow.com/questions/16286605/initialize-angularjs-service-with-asynchronous-data">AngularJS : Initialize service with asynchronous data</a> but don't quite understand how to implement the top-ranked answer (by joakimbl)</p>
  
  <p>What's the best way to expose the service and ensure it's not called by the controller until the internal async stuff has finished? Do I need to return the ENTIRE service as a promise rather than just the result from <code>getAllItems</code>? I had a go at this but am now confused. Thanks.</p>
  
  <p>EDIT</p>
  
  <p>I've also looked into using ui-router's <code>resolve</code> when loading the view <a href="http://blog.brunoscopelliti.com/show-route-only-after-all-promises-are-resolved" rel="nofollow noreferrer">http://blog.brunoscopelliti.com/show-route-only-after-all-promises-are-resolved</a> but that doesn't fix the internal readiness of the SQL data / factory. If I return the <code>getAllCases</code> method then it is still immediately called, there is nothing in the SQL database yet, the SQL query returns an empty results set, the promise resolves and the view is rendered.</p>