Offline apps using Ionic Framework, PouchDB and AngularJS

If you are a hybrid mobile application developer, you must have heard about Ionic Framework (built using AngularJS), AngularJS and PouchDB. I’ve hyperlinked these awesome products so you can catch up if your still living yesterday.

Today, I’m putting a simple tutorial on how I achieved offline data persistence on my Ionic apps using AngularJS and PouchDB. Offline Apps are apps you can use even without an Internet connection. When your device gets connected, it should sync changes made offline to your cloud database. Still not clear? Google it.

My approach is to use AngularJS services to make HTTP requests and save the response in an offline / client-side database. PouchDB allows cross-platform client DB storage. So you should be able to store data irrespective of browser support for different client DB technologies like WebSQL, Local Storage, IndexDB, SQLlite etc. Some require adapters to work though.


Step 1 : Include / Require / Depend on PouchDB

There are a couple ways to get PouchDB into your application code. I think the neatest so far is angular-pouchdb. I didnt go that route but if you’re cool with using promises, you should use it. I instead created an angularjs factory that returns an instance of PouchDB. I think / know factories and services in AngularJS are singletons, so only one instance of this object gets passed around when called.

This allows us to use “PouchDB” as a dependency in any AngularJS module in our application.

Step 2: Hooking into your existing HTTP request using AngularJS $http and services.

This is where the real business happens.. I have left comments on the methods in the angularjs service below. Ill do some explaining so we understand what we’re trying to achieve.

Ok, lines 1 -5 injects our dependencies into out “appDBBridge” service. This whole approach assumes your $http services return thennable promises. The “fetchAndSyncDataToScope” uses the “callServiceMethod” method to execute a method on a service which should return a promise. “fetchAndSyncDataToScope” then saves the response to a client-side db using PouchDB. “callServiceMethod” uses angularjs $injector to execute the service methods and “updateDBCollection” will store the response using the service name, the method and where necessary the documentid. AngularJS Ui-Router supports resolves .



this is what we’re trying to achieve. When our application loads or navigates to the ‘files’ state, the “userRootCabinet” runs and returns appDBBridge.selectOneDoc({}, ‘Filer.thisUserFiles’); which actually fetches any data existing in whatever PouchDB has saved offline. If you read the ui-router documentation, you should understand that.

resolve is an optional map of dependencies which should be injected into the controller.
If any of these dependencies are promises, they will be resolved and converted to a value before the controller is instantiated and the $stateChangeSuccess event is fired.

That means, if we have previously saved data, it gets loaded when we navigate to that state. If there isnt, we still get a resolved promise with ‘null’ so our controller can get instantiated. We now have an event that fires everytime the view is “$ionicView.enter”. The callback function here will use “fetchAndSyncDataToScope” to fetch new data from the server using the service and method supplied, update the database then update our $scope.

I hope this works from you, and I would love criticism, comments, improvements, comments. #codefunk