Chicken or Egg with Resolve and ngCordova SQLite


#1

In my Angular/Ionic App, I am trying to redirect an user to the state Setup when he opens the app for the first time, and has not setup his default account settings yet. To do this,

  • I use a database SQLite (from brodysoft in Phonegap Build consumed by ngCordova)
  • This database will contain a table Variables if and only if the the user has setup his account
  • Using UI-router, I attach a resolve function to the first state (Auth), see also below
  • The resolve function setupResolve() tries to retrieve the data from the table Variables, upon success it resolves the state ‘Auth’, upon failure it redirects the user to the state Setup

Here comes the issue:

  • To open the SQLite database and perform queries (such as SELECT), the device needs to be ready. In Ionic, this corresponds to wrapping the opening of the database and the queries inside the function $ionicPlatform.ready(){} - see a tutorial here.
  • However, the device will not be ready until all resolve functions are resolved.
  • But again, in order to resolve, the platform needs to be ready such that SQLite can be reached, which only can happen when all functions are resolved.

So as you see you get in a Chicken or Egg situation. Concretely, in my code below, the function ionicPlatform.ready() is not firing when opening the app on my device.

The strange thing is that it works fine on Google Chrome, but my guess is that the ionicPlatform.ready() is bypassed in the browser, or that there are other criteria.

// 
  // I-1
  self.openDb = function(method) {
    
    //
    var qOpen = $q.defer();
    $ionicPlatform.ready(function() {
      
      // ** NEVER REACHED WHEN USED IN RESOLVE CONTEXT **

      // Open Db
      if(window.cordova) {
        db = $cordovaSQLite.openDB("starter.db");
      } else {
        db = window.openDatabase("starter.db", "1.0", "My app", 1024 * 1024 * 100);
      }
      
      // Create Tables
      self.createTables().then(function(){
        qOpen.resolve(true);
      }, function(error){
        qOpen.reject(error);
      })
    })
    return qOpen.promise;
  };

state auth, code in .config

Note: the setupResolve function calls the function openDb()

.state('auth', {
    url: '/auth',
    templateUrl: 'templates/single-auth.html',
    controller: 'AuthCtrl',  
    resolve: {
      setupResolve: setupResolve
    }
  })

#2

Still having the issue


#3

So you’re thinking about the ready function a little wrong. It’s more getting the components ready. My app does the exact same thing (Only using local storage, but same principle). The best way to do this, is by using the splash screen. You can control when the splash screen hides in the code by changing some of the settings in the config.xml.

So my app will load, call the ready function, it lands on the login page initially however the splash screen is still showing so the user has no idea what’s actually happening. The app then tries the auth if it’s available, if not it will redirect them to the sign up screen then a timeout helps to hide the splash screen.

I don’t have access to my exact code but the splash screen is a cordova thing, so there are probably hundreds of tutorials on how to handle that.

I hope this can guide you in the right direction…