After my recent post, Crafting Native Looking iOS Apps with HTML, a number of you asked for an offline version that would use a Local Database (instead of the simple in-memory store) and provide a mechanism to automatically keep the local database in sync with a server database.
I’ll save automatic data synchronization strategies for a future post, but here is the first step: an “offline” version of the application that uses the device’s or the browser’s local database as its data provider. This version still uses Backbone.js as its architectural framework. Backbone.js makes it easy to change its default data access mechanism (which assumes RESTful services). You just replace the default Backbone.sync implementation and provide your own data access logic: in this case, some local SQL logic.
Web SQL vs IndexedDB
As you probably know, there have been two competing database APIs for HTML. From the W3C web site:
- The Web SQL specification defines an API for storing data in databases that can be queried using a variant of SQL. This specification is no longer in active maintenance and the Web Applications Working Group does not intend to maintain it further.
- The Indexed Database specification defines APIs for a database of records holding simple values and hierarchical objects. It is a working draft, and “work in progress”.
Even though the W3C is no longer actively maintaining the spec, this application uses the Web SQL API because, as a mobile app, its two main target platforms are iOS and Android, which both currently support Web SQL but not IndexedDB. More detailed platform support information can be found on caniuse.com (Web SQL and IndexedDB).
Chrome, Safari, and Opera on the desktop also support Web SQL, which means that you can run the application in these browsers. Try it here. For example, using the Chrome Developer Tools you could debug the application and inspect the database as shown in this screenshot:
Firefox and IE don’t support Web SQL. You could easily create an alternative version of EmployeeDAO (described below) that uses IndexedDB instead. You could also create a version of the application that uses either Web SQL or IndexedDB depending on the platform it’s running on.
Code Highlights
The source code is available in the localdb folder of the backbone-directory repository on GitHub. Here is a quick walkthrough…
The data access logic is encapsulated in EmployeeDAO, which also has a “populate” function to populate the employee table with sample data.
directory.dao.EmployeeDAO = function(db) {
this.db = db;
};
_.extend(directory.dao.EmployeeDAO.prototype, {
findByName: function(key, callback) {
this.db.transaction(
function(tx) {
var sql = "SELECT e.id, e.firstName, e.lastName, e.title, count(r.id) reportCount " +
"FROM employee e LEFT JOIN employee r ON r.managerId = e.id " +
"WHERE e.firstName || ' ' || e.lastName LIKE ? " +
"GROUP BY e.id ORDER BY e.lastName, e.firstName";
tx.executeSql(sql, ['%' + key + '%'], function(tx, results) {
var len = results.rows.length,
employees = [],
i = 0;
for (; i < len; i = i + 1) {
employees[i] = results.rows.item(i);
}
callback(employees);
});
},
function(tx, error) {
alert("Transaction Error: " + error);
}
);
},
findById: function(id, callback) {
// removed for brevity
},
findByManager: function(managerId, callback) {
// removed for brevity
},
populate: function(callback) {
// removed for brevity
}
});
Models are annotated with a “dao” attribute to indicate which data object to use to access their underlying data.
directory.models.Employee = Backbone.Model.extend({
dao: directory.dao.EmployeeDAO,
});
directory.models.EmployeeCollection = Backbone.Collection.extend({
dao: directory.dao.EmployeeDAO,
model: directory.models.Employee,
});
With that infrastructure in place, you can then override Backbone.sync to access data from the local database instead of RESTful services:
Backbone.sync = function(method, model, options) {
var dao = new model.dao(directory.db);
if (method === "read") {
if (model.id) {
dao.findById(model.id, function(data) {
options.success(data);
});
} else if (model.managerId) {
dao.findByManager(model.managerId, function(data) {
options.success(data);
});
}
// removed for brevity
}
};
Source Code
The source code is available in the localdb folder of the backbone-directory repository on GitHub.


Thank’s for a new post. LocalDb approach is very usefull. I wonder how difficult is to synchronize local database with server database. I am waiting for a new post about this subject.
Why doesn’t browser version work with iphone ?
Hi, there is a better approach for the backbone.sync? I am thinking in a bigger app with some other DAOS.
Maybe using the url property as it would be a RESTFULL app to decide how what DAO function to call?
Guys check this out….. If you have ideas on mobile apps for use on phones, submit ur apps a contest that gives you a chance to prove your mettle. Whether you are a professional developer or a student, every1 can submit their apps developed by using the Series 40 Web apps SDK and win.
Register today to submit ur apps….
http://bit.ly/ICUrkh
Hi,
this is very ideal tutorial for mobile application developers. But what I’m exactly looking for is accessing remote MySql database from android application.
I’d heghly appreciate your answer.
Prakash: I have been working on a few Android apps which will utilize the local SQLite database (using phonegap or native android). My plan is to build in a Synch process (kicked off when device is connected to the Internet).
The Synch process will then synch data with the MySQL database. I have it figured out in theory, but have not coded this process yet. Back in 2010, I wrote an application that did the same thing with Access databases (synching between a stand-alone tablet pc to a network version).
I’d love to know more if you have done something similar – or where you are with your coding. Please contact me via my website, http://www.ladysword.com. Thanks.
Hello, thank you for sharing so much information.
I’m going to check out more on github.
Hi,
i’m try to connect a simple app to existing sqlite db, i’ve create a db and add it to the xcode project (Resources folder) but when i start the simulator i see that the app find the file not in this folder but in a simulator path, how can set te real dbpath?
Thanks
These are the xCode log:
2012-09-03 11:31:21.417 staffLocale[2000:13403] Detected docs path: /Users/macbookpro/Library/Application Support/iPhone Simulator/5.0/Applications/69CEC18D-66D4-4B6C-89F5-AA543406FF60/Documents
2012-09-03 11:31:21.418 staffLocale[2000:13403] using dbPath: /Users/macbookpro/Library/Application Support/iPhone Simulator/5.0/Applications/69CEC18D-66D4-4B6C-89F5-AA543406FF60/Documents/employee.db
but this path not exist???
sir can you please explain where to store local db of phoneGap in android? and how to brows this db file? sir please help… I not getting the phonegap database idea..
Steve Carell’s face is just funny. Building Mobile Apps with HTML, can a person with little background on programming can just do it?
Hi I’m trying to create a simple contact info form for android and ipad that saves the info offline on a database then uploads to a server upon internet connection. This article seems like it is the answers to my prayers but I am too much of a newbie to understand what exactly to do, so for a simpleton like me would you mind “breaking it down” so a baby could do it?
This is definitely very useful for me. Being new into this space though, I am wondering what about the possibilities of somehow syncing a local and a remote db. Does anybody know anything about this?
For instance, I am building a small quiz app – I’d like the user to be able to use it without an internet connection, but I’d like their results to sync up to the main server when they have access.
Great blog right here! Additionally your site lots up very fast! What host are you using? Can I get your affiliate link on your host? I wish my web site loaded up as quickly as yours lol
hello nice blog thanks
I would like more information about this, because it is very nice., Thanks for sharing
Hi Christophe,
Your tutorials rock ! i learned so much about Backbone.js and Phonegap the last past days thanks to your blog posts :).
I was wondering if the way you populate the DB during app startup is ok for production use?
Should I store the data in a JSON file, load it during app start process and populate the DB with the data or is there a better way to do this ?