Hybrid Mobile apps have a challenging task of being as performant as native apps, but I

always tell other developers that it depends not the technology but how we code. The
Ionic Framework is a popular hybrid app development library, which uses optimal design
patterns to create awe-inspiring mobile experiences.

We cannot exactly use web design patterns to create hybrid mobile apps. The task of
storing data locally on a device is one such capability, which can make or break the
performance of your app. In a web app, we may use localStorage to store data but mobile
apps require much more data to be stored and swift access. Localstorage is synchronous,
so it acts slow in accessing the data. Also, web developers who have experience of coding
in a backend language such as C#, PHP, or Java would find it more convenient to access
data using SQL queries than using object-based DB.

SQLite is a lightweight embedded relational DBMS used in web browsers and web views
for hybrid mobile apps. It is similar to the HTML5 WebSQL API and is asynchronous in
nature, so it does not block the DOM or any other JS code. Ionic apps can leverage this
tool using an open source Cordova Plugin by Chris Brody (@brodybits). We can use this
plugin directly or use it with the ngCordova library by the Ionic team, which abstracts
Cordova plugin calls into AngularJS-based services. We will create an Ionic app in this
blog post to create Trackers to track any information by storing it at any point in time. We
can use this data to analyze the information and draw it on charts. We will be using
the ‘cordova-sqlite-ext’ plugin and the ngCordova library.

We will start by creating a new Ionic app with a blank starter template using the Ionic
CLI command, ‘$ ionic start sqlite-sample blank’. We should also add appropriate
platforms for which we want to build our app. The command to add a specific platform is
‘$ ionic platform add <platform_name>’. Since we will be using ngCordova to
manage SQLite plugin from the Ionic app, we have to now install ngCordova to our app.

Run the following bower command to download ngCordova dependencies to the local
bower ‘lib’ folder:

bower install ngCordova

We need to inject the JS file using a script tag in our index.html:

<script src=“lib/ngCordova/dist/ng-cordova.js"></script>

Also, we need to include the ngCordova module as a dependency in our app.js main
module declaration:

angular.module('starter', [‘ionic’,’ngCordova'])

Now, we need to add the cordova plugin for SQLite using the CLI command:

state('tracker'.com/litehelpers/Cordova-sqlite- storage. Our view will display a list of trackers from the SQLite DB table and also provide a feature to add a new tracker or delete an existing one. { url: '/'. but will display different entities. cordova plugin add https://github. controller:'TrackersListCtrl'.$urlRouterProvider){ $urlRouterProvider.git Since we will be using the $cordovaSQLite service of ngCordova only to access this plugin from our Ionic app.html' })}). We need to add the following config block code for our ‘starter’ module in the app. templateUrl: 'js/tracker-details/template.html' }). we need not inject any other plugin. { url: '/tracker/:id'. Both views would have similar functionality. We will have the following two views in our Ionic app:  Trackers list: This list showes all the trackers we add to DB  Tracker details: This is a view to show list of data entries we make for a specific tracker We would need to create the routes by registering the states for the two views we want to create. Create a new folder named trackers-list where we .config(function($stateProvider. templateUrl: 'js/trackers-list/template. controller:'TrackerDetailsCtrl'. $stateProvider.otherwise('/') $stateProvider.state('home'.js file only: .

db”). can store our controller and template for the view. .dataParams. The code for the runQuery function is as follows: function runQuery(query. $cordovaSQLite has a handful of methods to provide varying features:  openDB: This is a method to establish a connection to the existing DB or create a new DB  execute: This is a method to execute a single SQL command query  insertCollection: This is a method to insert bulk values  nestedExecute: This is a method to run nested queries  deleted: This is a method to delete a particular DB We see the usage of openDB and execute the command in this post. }.errorCb) { $ionicPlatform.dataParams). query.bind(this)).then(function(res) { successCb(res).This is a method to insert a new row for a new tracker into the table  deleteTracker .ready(function() { $cordovaSQLite.successCb. We will also abstract our code to access the SQLite DB into an Ionic factory.execute(db. We have to pass this object reference to our future $cordovaSQLite service calls. we will create a standard method runQuery to adhere to DRY(Don’t Repeat Yourself) principles. }.openDB(“myApp.This will get a specific Tracker from the cached list using an ID to display anywhere We will be injecting the $cordovaSQLite service into our factory to interact with our SQLite DB. function (err) { errorCb(err). In our factory. so we will store it in a module-level variable called db. We will implement the following methods:  initDB: This will initialize or create a table for this entity if it does not exists  getAllTrackers: This will get all trackers list rows from the created table  addNewTracker . We have to store the object reference returned from this method call. }). We can open an existing DB or create a new DB using the command $cordovaSQLite.This is a method to delete a specific tracker using its ID  getTracker .

[]. Now. and then delete a row. We will then call the execute method of the $cordovaSQLite service passing the ‘db’ object reference. runQuery(query.then’ method. the openDB method is used to establish connection with an existing DB or create a new DB. initDB Method: function initDB() { db = $cordovaSQLite. The method returns a promise to which we register callbacks using the ‘. We pass the results or error using the success callback or error callback.log("table created "). name string)". } In the preceding code. fetch all rows. We should always ensure that any cordova plugin code should be called when the cordova ready event is already fired. We define the columns ID with integer auto increment primary key properties with the name string. we will write code for each of the methods to initialize DB.ready() method.function(res) { console. and dataParams as arguments. Then. var query = "CREATE TABLE IF NOT EXISTS trackers_list (id in-teger autoincrement primary key. query.db"). we pass the query as a string. . we run the query to create a new table called ‘trackers_list’ if it does not exist. function (err) { console. } In the preceding code.log(err). }. which is ensured by the $ionicPlatform.openDB("myapp. }). dataParams (dynamic query parameters) as an array. and successCB/errorCB as callback functions. insert a new row.

return deferred.reject(error).promise.addNewTracker Method: function addNewTracker(name) { var deferred = $q.[name].defer(). We pass dynamic query parameters using the ‘?’ character in our query string. var query = "INSERT INTO trackers_list (name) VALUES (?)". }). We also use a $q library to return a promise to our factory methods so that controllers can manage asynchronous calls. deferred.function(response){ //Success Callback console.function(error){ //Error Callback console. which will be passed into the insert query. We write the insert query and add a new row to the trackers_list table where ID will be auto generated.log(error).resolve(response). runQuery(query. }. getAllTrackers Method: . } In the preceding code. we take ‘name’ as an argument. deferred.log(response). which will be replaced by elements in the dataParams array passed as the second argument to the runQuery method.

name }).item(i).id. rowsAffected giving the number of rows affected by the query and rows object with item method property.rows.i++){ $scope.id})" class="item-icon-right" ng-repeat="tracker in trackersList track by $index"> {{tracker. and it has the following query: var query = "SELECT * from trackers_list”.rows object into an utterable array of rows to be displayed using the ng-repeat directive: for(var i=0. } The code in the template to display the list of Trackers would be as follows: <ion-item ui-sref="tracker({id:tracker. The response object will have the following structure: { insertId: <specific_id>. which when resolved will give the response from the $cordovaSQLite method. to which we can pass the index of the row to retrieve it.name}} .rows.This method is the same as the addNewTracker method.trackersList. length: <total_no_of_rows>} rowsAffected: 0} The response object has properties insertId representing the new ID generated for the row.i<response. We will write the following code in the controller to convert the response. rows: {item: function. This method will return a promise. name:response.push({ id:response. only without the name parameter.rows.length.item(i).

packtpub.in.[id]. tracker_id.defer(). You can implement your own version of this app or even use this sample code for any other use case. used for this table.com/books/content/how-use-sqlite-ionic-store-data .function(response){ … [Same Code as addNewTrackerMethod]} The delete tracker method has the same code as the addNewTracker method. We pass ‘id’ as the argument to be used in the WHERE clause of delete query to delete the row with that specific ID. <ion-delete-button class="ion-minus-circled" ng- click=“deleteTracker($index.id)"> </ion-delete-button> <i class="icon ion-chevron-right”></i></ion-item> deleteTracker Method: function deleteTracker(id) { var deferred = $q. where the only change is in the query and the argument passed. http://nextflow. The trackers details view will be implemented in the same way to store data into the tracker_entries table with a foreign key. runQuery(query. It will also use this ID in the SELECT query to fetch entries for a specific tracker on its detail view.th/en/2015/easy-way-to-work-with-sqlite-database-in-ionic-framework/ https://www.tracker. Rest of the Ionic App Code: The rest of the app code has not been discussed in this post because we have already discussed the code that is intended for integration with SQLite. var query = "DELETE FROM trackers_list WHERE id = ?".