Create A Todo List Mobile App Using Ionic Framework

Since writing my two tutorials regarding using SQLite in Ionic Framework and shipping an app with a pre-populated database, I’ve received many requests for a tutorial for making a full blown app.  I listen to my readers, so I figured what better way to show such an example, than to create a todo-list type application.

In this tutorial, I hope to accomplish the following:

  • Shipping a pre-populated / pre-filled SQLite database
  • Access the SQLite database and perform operations based on user input
  • Include a WebSQL alternative for testing via a web browser
  • Navigate between views using the AngularJS UI-Router
  • Remove todo items from your list using swipe gestures

All items that I wish to accomplish have seen their own tutorials.  If you’re familiar with the Marvel comic book movies, you’ll know that every hero has their own story, then they meet up for the bigger picture in an Avengers movie.  Think of this tutorial like that.

You’ve probably come to expect this by now, but let’s go ahead and create a fresh Ionic Framework project to work with:

It is important to note that if you’re not using a Mac, you cannot add and build for the iOS platform.

Before we go any further, I’d like to strongly recommend you check out the tutorials I made for each component listed.  This major tutorial won’t offer the depth that I did on each of the components which is why I suggest you continue from this point with a strong knowledge of everything we’re about to do.

Setting up our plugins and libraries

With our project as the current working directory, lets add all the plugins we plan to use in this project:

Our Apache Cordova plugins will work fine at this point, but because we’re using Ionic Framework, it is best to use the AngularJS extension set, ngCordova.  Since ngCordova is still alpha / beta, I’m not going to recommend you download the latest version when following this tutorial because you could be viewing this tutorial many months after it was published.  With alpha and beta libraries, breaking changes can be introduced at any time.  With that said, I’m going to recommend you download project commit 5eaa5552fd from GitHub since it is what I’m using in the tutorial.

Extract the ngCordova archive you downloaded and include ng-cordova.min.js into your project’s www/js directory.

Now crack open your www/index.html file because we need to include the script in our project:

Notice that I’ve included ng-cordova.min.js above the cordova.js line?  It is very important you do that, otherwise you’re going to get a mess of strange results.

The last thing we need to do in regards to including ngCordova into our project is we need to include the directive in our angular.module found in our www/js/app.js file:

Whats our plan?

Now that all the plugins and libraries are installed, it is time to explain what we’re trying to accomplish.  Our todo list application will consist of four screens:

  1. A setup / configuration screen
  2. A list of categories
  3. A list todo list names that go with a particular category
  4. A list of todo list items that go with a particular todo list name

The pre-filled SQLite database that we ship with our application will contain a list of categories.  If we are testing in a web browser, we will pre-populate the database via a script instead since it cannot be copied over.  For the purpose of this example, the category list cannot be changed.  However, we will be able to add and remove any todo list name or todo list item.

Preparing our database

Let’s start by creating a SQLite database with the following table structure.

  • populated.db
    • tblCategories
      • id: integer auto increment
      • category_name: text
    • tblTodoLists
      • id: integer auto increment
      • category_id: integer
      • todo_list_name: text
    • tblTodoListItems
      • id: integer auto increment
      • todo_list_id: id
      • todo_list_item_name: text

You can poke fun at my tables all you want, but they’ll accomplish the task at hand.  Now using your favorite SQLite client, add some categories to the tblCategories table.

It is finally time to start programming the application!

Configuring your UI-Router for navigation

Create a directory in your www folder called templates and add the following three files:

  • www
    • templates
      • config.html
      • categories.html
      • lists.html
      • items.html

Inside your www/js/app.js file add the following angular.module.config method to your code:

We will always start in the config view.  It will be the place that our database is copied over and loaded from.  When navigating between views we will be passing the unique id values obtained from our SQLite database.  We’ll get to that later though.  It is time to create each of the expected controllers based on what we put into the UI states.  In your www/js/app.js file, add the following controllers:

Go ahead and open your www/index.html file because we need to tell it that we’ll be using states in our application:

We aren’t quite done yet.  We need to add some code to our template files so the router can pick them up as templates.  In each of the four template files, add <ion-view></ion-view>.  Ignore how simple they are as we’re going to improve upon them later.

Adding our SQLite database to the project

This can get a little nutty here if you’re not careful, so please consult my other tutorials if you get into a jam.  One major difference here between this tutorial and my others is that we will be processing SQLite via a controller rather than in the method.  This is because it is my understanding that many people will be trying to work with very large SQLite databases that are too large to be processed in the run method.

Add the following to your ConfigController in your www/js/app.js file:

Notice the highlighted lines in particular.  We are first checking to see if window.cordova exists and if it doesn’t, it means we are using a web browser.  On the device we are copying over the populated database and opening it.  We don’t have that luxury with WebSQL, so we need to create all the tables if they don’t exist.  Because we are lazy and don’t want to check if the table data exists, we are going to drop the categories table every time and re-populate it.  It won’t mess up any keys in the other tables.

Querying our database

We have three controllers that will be querying the database in different ways.  Our CategoriesController will be doing a select-all, for all categories in the table.  You can accomplish this task by doing the following:

All categories are translated into JSON and added to the scope which we can then use directly in our categories view.  However, notice that we are wrapping the SQL in $ionicPlatform.ready().  This is because we cannot try to query the database until our plugins are ready.

Let’s go ahead and finish up our other controllers.  I suggest you brush up on your SQL knowledge if you’re rusty.

Notice the repetitiveness of the code?  It can be avoided if you want to put in the effort, but for the simplicity of this example I decided to leave it as is.  Again all we’re doing is querying the tables for all data and converting the results into a JSON object that can be cycled through in our view.  The methods of inserting we’re using will initiate a popup rather than a new page.

Designing each of our views

Now that all of our data is being queried as it should and our states are configured, it is time do do a little UI development.  Each of our three templates will be near identical, so open each of them and add the following:

Nothing really crazy happening here.  We just print out the data in a list.  However on the categories and lists view we pass the id when we click on an element.  That id is picked up in the $stateParams in the controller.

Todo App Categories Todo App Lists Todo App Items

Removing SQLite records with gesture controls

So at this point we have shipped a pre-populated SQLite database in a mobile Ionic Framework application that has three views.  We can add new todo lists in a specific category and add todo items in a specific todo list.  Sounds like we have a pretty solid application at the moment.  This is not correct yet.  We need to be able to remove todo lists or items.

For simplicity, our logic is going to be wrapped around the following for removing records.  If we want to remove a single todo item, go ahead and remove it, but if we want to remove a todo list, then remove the list and all items that are assigned to it.

Starting in our ItemsController add the following function:

What’s going to happen is we’re going to pass in the item we want to delete, then we are going to remove it from the database, and then we are going to remove it from the scope.

Next we are going to modify our items.html template so our list looks like this:

Notice how we added logic for swipe options.  Similar can be added for lists.html but this time we will be deleting all items as well as the list.  Again, here is our delete function which will delete from both levels:

And then here is our lists.html template changes to go with it:

Todo App Items Delete


With a little bit of luck, you were able to follow all my instructions and create a fabulous todo list application that made use of various topics that I’ve covered previously on my blog.  If you run into issues, I encourage you to look at my previous articles before asking for help in the comments.  I am happy to help, but you’ll learn it better if you first do the research.

A video version of this article can be seen below.

Nic Raboy

Nic Raboy is an advocate of modern web and mobile development technologies. He has experience in Java, JavaScript, Golang and a variety of frameworks such as Angular, NativeScript, and Apache Cordova. Nic writes about his development experiences related to making web and mobile development easier to understand.

  • Фаёзжон Бердиев

    Share the source please =)

    • I don’t post the full source because I’d like to think the write-up in combination with the video tutorial is enough to accomplish the task. If there are holes in the tutorial or you’re running into trouble, I encourage you to ask questions.


  • Hi Nic.
    When I inject $cordovaSQLite to run() function and open browser, I have the following error:

    “Error: [$injector:unpr] Unknown provider: $cordovaSQLiteProvider <- $cordovaSQLite”

    What did I miss?
    Thank you.

    • My guess is you’ve got a typo somewhere or you forgot to include ngCordova in your project.


  • Shonek

    Hi, could you share the database file please? I am having problems reading the database, but I dont know if the problem is in my database file or not. The error is:

    “no such table: tblCategories (code 1): , while compiling: SELECT id, category_name FROM tblCategories”

    I have created it in Ubuntu with DB Browser for SQLite, thanks.

    • When you create your SQLite database, build it with this:

      Those are the exact commands that I plugged into my SQLite creation tool.


  • Adil Mourahi

    thanks for sharing and helping.

    One question please :

    Where is the file “populated.db” , i say it was in your “www” diretory, but, for me, the application not stop if i deleted this file. so, where is the my file “populated.db” ? .
    Sorry, english is not my first language.

    • The database only gets moved once. So if the application is installed and you remove the database from your code and re-install, it will still exist on the device.

      Per the plugin owners documentation, the www folder is the correct location to put your database file.


  • Hendra Wijaya

    Hi Nic,
    Can i know what android emulator did you use to testing in this video tutorial ??
    i’m waiting your reply, Thanks.

    • I am using Genymotion in my videos

      • Hendra Wijaya

        Thanks Nic, its a pain debug using android AVD

  • Jeremy

    I follower your tutorial it’s great.
    I just have on problem. When I refresh the page I get a blank screen. And if I emulate on iOS I get one too.
    The only thing in the console ist: null is not an object (avaluating ‘n.transaction’).
    Have you expreienced this prblem or anyone else?

    Thank you

    • My assumption for your error is because you lose tie to the database during the refresh. We handle most of the database stuff from the ConfigController so when you refresh from a different screen that information becomes lost.

      My recommendation is do not test in a browser. Do not use Ionic serve. And do not use live reload.


  • Anil Kumar


    Here its unable to copy the file populate.db and it is not there in my project and it is showing the error as

    Uncaught TypeError: Cannot read property ‘sqlDB’ of undefined

    • If sqlDB is undefined, it means your plugin is not working correctly. You sure it is installed?

      Can you share your full logs?


      • Anil Kumar

        yeah it is working now. Thank you very much for your blog, It’s awesome but I picked these site when I am searching in google for SQLite for ionic framework , I tried this example from this site but you didn’t mention, that this is not the starting step to start the SQLite plugin for Ionic frame work.

        Again I revisited your whole blog I came to know these are the steps

        1.Use SQLite Instead of Local Storage In Ionic Framework
        2.Deploy Ionic Framework App With Pre-Filled SQLite DB
        3.Create A Todo List Mobile App Using Ionic Framework

        Thanks & Regards
        Anil Kumar

        • I mentioned in in the first sentence of the article. I’m glad you got it working though 🙂


  • jome

    while adding platform in my application execvp(): Permission denied error showing please help to find a solution

    • Sounds like your Ionic Framework, NPM, Apache Cordova, or Android was not installed correctly on your system. I encourage you to give more details on the issue in the official forums.


  • Dennis “Dauntless” McAddTee

    Hi Nic, this has been extremely helpful. i have been trying to add checkboxes to a similar app but i have no idea how to implement it, could you help me please?

    • I recommend reading the official Ionic documentation to get information on how to use checkboxes in your application.


  • Marouane Elmidaoui

    hi , i get a problem :
    Cross origin requests are only supported for protocol schemes ….

    what is the solution

  • ryan

    Hi Nick, Thank for great tutorial. Working great except one issue, ionicHistory injection. It doesn’t work for me. I can’t inject it. So I commented it out. Could you help me that one? And I search how to use $ionicPlatform.registerBackButton to use as native app. Could you make one tutorial about it?
    Thank for your knowledge sharing? 🙂

  • Kevin Angulo

    Hi, i did everything that you did in this awesome tutorial, but when I run in chrome browser, no show categories, app create database and insert categories but i think that fails in this line $location.path(“/categories”);, no error show in console, but no redirect to categories list, aparently everythings is fine, i browse the data of websql.db and it have data. I dont know what more to do, so please, if u can give me any clue, i would appreciated. Thank You.

    this is my code

    url: “/config”,
    templateUrl: “templates/config.html”,
    controller: “ConfigController”
    url: “/categories”,
    templateUrl: “templates/categories.html”,
    controller: “CategoriesController”
    url: “/lists/:categoryId”,
    templateUrl: “templates/lists.html”,
    controller: “ListsController”
    url: “/items/:listId”,
    templateUrl: “templates/items.html”,
    controller: “ItemsController”


    todoApp.controller(“ConfigController”,function($scope, $ionicLoading, $ionicPlatform, $ionicHistory, $cordovaSQLite, $location) {

    disableAnimate: true,
    disableBack: true

    ${ template: “Loading…”});
    window.plugins.sqlDB.copy(“test.db”, function(){
    db = $cordovaSQLite.openDB(“test.db”);
    db = $cordovaSQLite.openDB(“test.db”);
    } else {
    db = openDatabase(“websql.db”,”1.0″,”My WebSQL Database”, 2 * 1024 * 1024);
    tx.executeSql(“DROP TABLE IF EXISTS tblCategories”);
    tx.executeSql(“CREATE TABLE IF NOT EXISTS tblCategories (id integer primary key, category_name text)”);
    tx.executeSql(“CREATE TABLE IF NOT EXISTS tblTodoLists (id integer primary key, category_id integer, todo_list_name text)”);
    tx.executeSql(“CREATE TABLE IF NOT EXISTS tblTodoListItems (id integer primary key, todo_list_id integer, todo_list_item_name text)”);
    tx.executeSql(“INSERT INTO tblCategories (category_name) VALUES (?)”,[“Shopping”]);
    tx.executeSql(“INSERT INTO tblCategories (category_name) VALUES (?)”,[“Chores”]);
    tx.executeSql(“INSERT INTO tblCategories (category_name) VALUES (?)”,[“School”]);

    • What do your logs say?

      • Kevin Angulo

        Nothing, but after restart machine it works like a charm, i dont know what happend, maybe some issue with cache.

        • That is weird, but I’m glad you got it working 🙂

  • Peter


    thanks for your tutorial. Poorly i am getting following error


    0 335490 error Uncaught SyntaxError: Unexpected token ., http://localhost:8101/js/app.js, Line: 9

    1 335504 error Uncaught Error: [$injector:modulerr] Failed to instantiate module starter due to:

    Error: [$injector:nomod] Module ‘starter’ is not available! You either misspelled the module name or forgot to load it. If regi
    stering a module ensure that you specify the dependencies as the second argument.$injector/nomod?p0=starter
    at http://localhost:8101/lib/ionic/js/ionic.bundle.js:8762:12
    at http://localhost:8101/lib/ionic/js/ionic.bundle.js:10466:17
    at ensure (http://localhost:8101/lib/ionic/js/ionic.bundle.js:10390:38)
    at module (http://localhost:8101/lib/ionic/js/ionic.bundle.js:10464:14)
    at http://localhost:8101/lib/ionic/js/ionic.bundle.js:12796:22
    at forEach (http://localhost:8101/lib/ionic/js/ionic.bundle.js:9022:20)
    at loadModules (http://localhost:8101/lib/ionic/js/ionic.bundle.js:12780:5)
    at createInjector (http://localhost:8101/lib/ionic/js/ionic.bundle.js:12706:11)
    at doBootstrap (http://localhost:8101/lib/ionic/js/ionic.bundle.js:10144:20)
    at bootstrap (http://localhost:8101/lib/ionic/js/ionic.bundle.js:10165:12)


    Actually i can’t see any problem with module starter.

    What might be the problem?


    • Looks like you probably have a typo somewhere. I get that error occasionally when I misspelled something or forgot a bracket.


    • adalberto Joco

      The module isnt starter, is todoApp

      • It is starter, not todoApp:

        todoApp is just a variable name, not a module name.


        • adalberto Joco

          Its true 🙂 I was following my exercise where I didnt use var, but todoApp in the module name.

  • gorilla

    Is there a package of this project available for download?

    • I don’t provide packages. With the write-up and video there should be more than enough to go off of to reproduce what I did. If you’ve followed my guides and are having issues, ask questions.


  • Akshay

    I followed this tutorial and created my own todoApplication from scratch, but it works fine on web browser but when i build and deploy the apk file to an android device, the first time the application crashes. Then on launching the application again it does not crash but it only shows the header with the name Categores on it….nothing else…
    Please help…i have a deadline for creating a successfully working database driven ionic app for android

    • What do your logs say?

    • Rajesh d m

      Did you find a solution to your problem ?
      I am experiencing the same problem

  • Rajesh d m

    could you please explain how this app can be made without the use of WebSQL, similar to other tutorial where the database is opened in the run method itself?
    thanks in advance

    • This tutorial only uses WebSQL if you’re running from a web browser since the SQLite plugin only works with Android or iOS. When running from a device or emulator, WebSQL will not be used.


      • Rajesh d m

        can you please share your prefilled database
        and where exactly should the database file be stored? in the www folder just when you enter the project ?

        thanks in advance

        • Per the official plugin documentation:

          You’ll have to create your own SQLite database. I am not going to upload one.


          • Rajesh d m

            Their documentation says the function has 4 parameter, but in your example you have used only 3 parameters

            window.plugins.sqlDB.remove(dbname, location, success,error);

            has the plugin changed recently or am I looking at something wrong

            Thanks in advance

          • Looks like the plugin changed 11 days ago.

            Try using 0 as the location like the plugin documentation says. Then report back.


          • Rajesh d m

            im still experiencing the same problem – its not going to any page – its going to the error block of windows.copy . I am guessing its not able to find my db at all.

          • With the command fixed, completely wipe out the installation and re-install. If that fails I suggest opening an issue ticket with the plugin developer.


          • Rajesh d m

            yup, reinstalling solved that problem. Its now not going into the error block but the right function.

            new problem has come up, its no longer working in the browser (or the app),

            It says my DB is null, i dunno why
            Here is my error log – the line where the error occurs is

            — – — $cordovaSQLite.execute(db, query, []).then(function(res) —-


            TypeError: Cannot read property ‘transaction’ of null

            why exaclty could this be happening ?

            Thanks in advance

          • Sounds like you’re getting close to the solution. Mind putting your full project on GitHub? I’ll take a look at it if you do.


          • Rajesh d m

            I have uploaded the code on github on this link


            Please take a look and tell me where im wrong

            Thanks in advance

          • I tried it myself and it seems like the BrodySoft SQLite plugin is broken.

            I’m going to try a few things over the week, but my guess is we will need to open an issue ticket for the developer.

            I’ll keep you posted.

          • Rajesh d m

            so it isn’t working in the browser also ? or just the device because it is not working in the browser also for me

            Thanks in advance

          • shahril

            I think you forgot to put this code

  $ionicPlatform, $cordovaSQLite) {…}

  • Declan Murphy

    I don’t know if you do tutorial requests, but I would love to see one about syncing a database’s records with a server. Also if the data could be compressed as well?

    • To keep comments relevant to the topics they are attached to, please direct any request or non-relevant question to my Twitter.


  • The SQLite binary the app installs is not compatible with Lollipop =/

    • Says who? Please link to documentation proving this.


      • Thanks for attention,

        Here is a link that says this:!topic/tasker/raFenn0NJTM

        The solution that they give did not work for me

      • Sorry, now is running!

        By using the option to inspect devices in google chrome I found out that I was failing to copy the database.

        When fall into the transaction, the variable “db” was null and there happened the problem.

        As I was checking through “adb shell”, when I executed the command “sqlite3 populated.db” returned the error “independent executables (PIE) are supported.”

        I was researching and tried changing API, etc … But it was not the real problem.

        The solution was let like this:

        if (window.cordova) {
        window.plugins.sqlDB.copy(“populated.db”, function () {
        db = $cordovaSQLite.openDB(“populated.db”);
        }, function (error) {
        console.error(“There was an error copying the database: ” + error);
        db = $cordovaSQLite.openDB(“populated.db”);
        } else {
        db = openDatabase(“websql.db”, ‘1.0’, “My WebSQL Database”, 2 * 1024 * 1024);

        if (db == null)
        db = $cordovaSQLite.openDB(“populated.db”);

        db.transaction(function (tx) { … }


        Still not showing the data in the index page, but I’m working in this…hahaha


  • shahril

    D/AndroidRuntime( 1647): Shutting down VM

    D/CordovaWebViewImpl( 1658): onPageDidNavigate(file:///android_asset/www/index.html)

    D/JsMessageQueue( 1658): Set native->JS mode to OnlineEventsBridgeMode

    D/CordovaWebViewImpl( 1658): onPageFinished(file:///android_asset/www/index.html#/config)

    I/Choreographer( 1658): Skipped 35 frames! The application may be doing too much work on its main thread.

    D/SystemWebChromeClient( 1658): file:///android_asset/www/cordova.js: Line 1185 : deviceready has not fired after 5 seconds.

    I/chromium( 1658): [INFO:CONSOLE(1185)] “deviceready has not fired after 5 seconds.”, source: file:///android_asset/www/cordova.js (1185)

    D/SystemWebChromeClient( 1658): file:///android_asset/www/cordova.js: Line 1178 : Channel not fired: onPluginsReady

    I/chromium( 1658): [INFO:CONSOLE(1178)] “Channel not fired: onPluginsReady”, source: file:///android_asset/www/cordova.js (1178)

    D/SystemWebChromeClient( 1658): file:///android_asset/www/cordova.js: Line 1178 : Channel not fired: onCordovaReady

    I/chromium( 1658): [INFO:CONSOLE(1178)] “Channel not fired: onCordovaReady”, source: file:///android_asset/www/cordova.js (1178)

    I/App ( 1658): WARNING: Back Button Default Behavior will be overridden. The backbutton event will be fired!

    D/SystemWebChromeClient( 1658): file:///android_asset/www/plugins/cordova-plugin-console/www/console-via-logger.js: Line 173 : There was an error copying the database :OK

    I/chromium( 1658): [INFO:CONSOLE(173)] “There was an error copying the database :OK”, source: file:///android_asset/www/plugins/cordova-plugin-console/www/console-via-logger.js (173)

    D/PluginManager( 1658): exec() call to unknown plugin: Console

    D/SystemWebChromeClient( 1658): file:///android_asset/www/lib/ionic/js/ionic.bundle.js: Line 20434 : TypeError: Cannot read property ‘transaction’ of null

    D/SystemWebChromeClient( 1658): at Object.execute (file:///android_asset/www/js/ng-cordova.min.js:9:7454)

    D/SystemWebChromeClient( 1658): at file:///android_asset/www/js/app.js:87:20

    D/SystemWebChromeClient( 1658): at file:///android_asset/www/lib/ionic/js/ionic.bundle.js:44991:19

    D/SystemWebChromeClient( 1658): at Object.ionic.Platform.ready (file:///android_asset/www/lib/ionic/js/ionic.bundle.js:2122:9)

    D/SystemWebChromeClient( 1658): at Object.self.ready (file:///android_asset/www/lib/ionic/js/ionic.bundle.js:44989:26)

    D/SystemWebChromeClient( 1658): at new (file:///android_asset/www/js/app.js:85:18)

    D/SystemWebChromeClient( 1658): at invoke (file:///android_asset/www/lib/ionic/js/ionic.bundle.js:13012:17)

    D/SystemWebChromeClient( 1658): at Object.instantiate (file:///android_asset/www/lib/ionic/js/ionic.bundle.js:13020:27)

    D/SystemWebChromeClient( 1658): at file:///android_asset/www/lib/ionic/js/ionic.bundle.js:17289:28

    D/SystemWebChromeClient( 1658): at self.appendViewElement (file:///android_asset/www/lib/ionic/js/ionic.bundle.js:48435:24)

    I/chromium( 1658): [INFO:CONSOLE(20434)] “TypeError: Cannot read property ‘transaction’ of null

    I/chromium( 1658): at Object.execute (file:///android_asset/www/js/ng-cordova.min.js:9:7454)

    I/chromium( 1658): at file:///android_asset/www/js/app.js:87:20

    I/chromium( 1658): at file:///android_asset/www/lib/ionic/js/ionic.bundle.js:44991:19

    I/chromium( 1658): at Object.ionic.Platform.ready (file:///android_asset/www/lib/ionic/js/ionic.bundle.js:2122:9)

    I/chromium( 1658): at Object.self.ready (file:///android_asset/www/lib/ionic/js/ionic.bundle.js:44989:26)

    I/chromium( 1658): at new (file:///android_asset/www/js/app.js:85:18)

    I/chromium( 1658): at invoke (file:///android_asset/www/lib/ionic/js/ionic.bundle.js:13012:17)

    I/chromium( 1658): at Object.instantiate (file:///android_asset/www/lib/ionic/js/ionic.bundle.js:13020:27)

    I/chromium( 1658): at file:///android_asset/www/lib/ionic/js/ionic.bundle.js:17289:28

    I/chromium( 1658): at self.appendViewElement (file:///android_asset/www/lib/ionic/js/ionic.bundle.js:48435:24)”, source: file:///android_asset/www/lib/ionic/js/ionic.bundle.js (20434)

    I/art ( 1658): Background sticky concurrent mark sweep GC freed 142353(2MB) AllocSpace objects, 1(16KB) LOS objects, 30% free, 4MB/6MB, paused 1.652ms total 105.563ms

    W/SQLiteConnectionPool( 1658): A SQLiteConnection object for database ‘/data/data/com.ionicframework.todoapp988986/databases/populate.db’ was leaked! Please fix your application to end transactions in progress properly and to close the database when it is no longer needed.

    Hi Nic ! Your tutorial is awesome and I already followed your tutorial. In browser this application working 100% . But, when I deploy at android emulator I got this error . My database “populate.db” already copied at www directory. So, what is the solution to fix my problem ?

  • Hridaya Kandel

    Is this project available in github?

    • No, I typically don’t put my tutorials on GitHub. I’ve given a full writeup in addition to a video where I develop the application from scratch. Should be enough to go off of. If you have questions, I’d be happy to answer them.


  • shahril

    Hello Nic, before this I ask you some questions about problems I faced and I have followed your tutorial and it working 100%.

    But I am now facing another issue, very first time my application launched fine, but if I kill my application and comeback again it just shows me “loading”. To make it run again, I need to clear up the data from app settings or reinstall, any thoughts?

    • What do your logs say?

      • shahril

        I/ActivityManager( 1298): Start proc 2029:com.ionicframework.kdmatest496024/u0a76 for activity com.ionicframework.kdmatest496024/.MainActivity

        I/CordovaLog( 2029): Changing log level to DEBUG(3)

        I/WebViewFactory( 2029): Loading version 39 (1737576-x86_64) (code 300008)

        V/WebViewChromiumFactoryProvider( 2029): Binding Chromium to main looper Looper (main, tid 1) {3f1f904b}

        I/LibraryLoader( 2029): Expected native library version number “”,actual native library version number “”

        I/chromium( 2029): [] Chromium logging enabled: level = 0, default verbosity = 0

        I/BrowserStartupController( 2029): Initializing chromium process, singleProcess=true

        W/art ( 2029): Attempt to remove local handle scope entry from IRT, ignoring

        W/chromium( 2029): [] locale_file_path.empty()

        I/chromium( 2029): [] Load from apk succesful, fd=29 off=46184 len=3037

        I/chromium( 2029): [] Loading webviewchromium.pak from, fd:30 off:229484 len:1089587

        E/chromium( 2029): [] No suitable EGL configs found.

        E/chromium( 2029): [] GLSurfaceEGL::InitializeOneOff failed.

        E/chromium( 2029): [] GLSurface::InitializeOneOff failed

        W/chromium( 2029): [] SPDY proxy OFF at startup

        D/SystemWebViewEngine( 2029): CordovaWebView is running on device made by: unknown

        V/WindowManager( 1298): Adding window Window{2b0c846c u0 com.ionicframework.kdmatest496024/com.ionicframework.kdmatest496024.MainActivity} at 2 of 8 (before Window{892362f u0 Starting com.ionicframework.kdmatest496024})

        D/CordovaActivity( 2029): Started the activity.

        D/CordovaActivity( 2029): Resumed the activity.

        D/gralloc_goldfish( 2029): Emulator without GPU emulation detected.

        I/ActivityManager( 1298): Displayed com.ionicframework.kdmatest496024/.MainActivity: +590ms

        D/CordovaWebViewImpl( 2029): onPageDidNavigate(file:///android_asset/www/index.html)

        D/JsMessageQueue( 2029): Set native->JS mode to OnlineEventsBridgeMode

        D/CordovaWebViewImpl( 2029): onPageFinished(file:///android_asset/www/index.html#/config)

        I/App ( 2029): WARNING: Back Button Default Behavior will be overridden. The backbutton event will be fired!

        D/TaskPersister( 1298): removeObsoleteFile: deleting file=243_task.xml

        I/MediaFocusControl( 1298): AudioFocus abandonAudioFocus() from [email protected]kService[email protected]

        • There are no errors in what you pasted me so either you didn’t paste all the logs, or it is just a problem in your logic, not the plugins or setup.

          Maybe put your full project on GitHub and I’ll take a look.


          • shahril

            yeah….but for the first time I launched at my emulator, it is working and no error at adb logcat. I can insert the data into sqlite db and retrieve the data. After I restart or kill my application, stuck at config.html. To make it run again, I go to app setting->my application and clear up the data, after that the application run and working like first time I launched at emulator. In logic php and mysql, when we open the connection database, we should close the connection after an operation. But, in sqlite with ionic we use method openDB(‘my.db). So,is there any way in sqlite to close the database like in php concept for example db.close() and is there due to my mobile application didn’t work ? sorry, bad english 🙂

          • Can’t help you without seeing your code.

          • shahril

            OK…solved . In my controller I forgot to put 0 at parameter window.plugins.sqlDB.copy(“populated.db”, 0, function() . Btw, thanks master. 🙂
            I got new project to develop mobile apps using ionic+SQLite. Do you have a tutorial about sync some data from mysql to SQLite database in mobile apps ?

          • I don’t recommend implementing sync to / from a relational database. It will cause you a lot of time and headache.

            Instead you might look at something like this:



  • Hridaya Kandel

    i always get this error in console when running app in device..

    0 290836 error TypeError: Cannot read property ‘transaction’ of null





    14), <ion-nav-view name=”tab-setting” class=”view-container tab-content” nav-vie

    w=”active” nav-view-transition=”android”>

    1 291070 log OPEN database: my.db

    2 291075 log new transaction is waiting for open operation

    3 291076 log new transaction is waiting for open operation

    JS changed: F:ionic_projectkrishigharwwwjsservices.js

    0 290836 error TypeError: Cannot read property ‘transaction’ of null





    14), <ion-nav-view name=”tab-setting” class=”view-container tab-content” nav-vie

    w=”active” nav-view-transition=”android”>

    1 291070 log OPEN database: my.db

    2 291075 log new transaction is waiting for open operation

    3 291076 log new transaction is waiting for open operation

    • I see the following in your logs:

      Stop using Ionic Serve, Ionic View, and Ionic Live-Reload. They do not work properly with native device plugins.


  • Mr J

    how to take backup of db which is made for to do app

    • What kind of backup were you looking to take? Backup to Google Play / iCloud, your own API, a CSV file? I need more information.


  • Bernhard Zürn

    Tried to implement it, but Lists view is just empty without any errors after i tap on a category

    • I’m betting there are errors. Please paste your device logs in a comment.


      • Bernhard Zürn

        You are 100% right. The Bugs are fixed now an my Implemantation works 🙂 Thanks a lot !

        By the way have you already had a look at the Supersonic Framework from AppGyver ? It was presented in the german magazin Beside a UI-COmposer tool it has other advantages over ionic. It uses multiple WebViews and can load them from memory so the user does not have to wait for css to render like in ionic were everything runs in one single webview.

  • Boogie Das

    hey nic each time i try to do this stuff it pops and error and says” db is not defined ” and in have tried several ways to make db verified

  • NN

    Hi, thanks for tutorial

    Just could you help me with a question, I am not able to see data which exist in db file.
    I have created an app which have some list of rows, the rows should be filled from db. I have created the db file and put it on {{asserts/www}} folder, but anyway my list is empty and seems it even don’t see the db file.

    What can this be?

  • Manuel Arango

    Hi Nic, i want to thank you for your tutorial; i’ve been putting a lot of effort to understand everything as much as i can and i appreciate that you could help me with an error i’m getting, i wouldn’t botter you unless it was absolutely neccesary because i already tried to solve this myself but i’m not getting anywhere, i’m getting the following error:

    ( ReferenceError: ‘openDatabase’ no está definido ) wich means (ReferenceError: ‘openDatabase’ is not defined ),

    i get this error testing in ionic serve and the whole app freezes in the initial config showing me the Loading… of $ionicLoading, i supose the error is in the next line as implied by the console:

    (db = openDatabase(“websql.db”, “1.0”, “My WebSQL Database”, 2 * 1024 * 1024))

    when i run the app in smartphone it just shows me the Ionic Blank Starter header and a white background, if i inspect it with chrome DevTools i don’t get to see any IndexedDB or Web SQL so i’m thinking it is not creating any database at all. You have any clue what the error might be?

    • Rule #1, never use ionic serve, ionic view, or ionic live-reload when developing Ionic apps. They are alpha / beta services, and quite honestly, they suck in their current state.

      Please try to build an APK of your application and then install it to a device or simulator. Let me know the new results if it continues to not work.


      • Manuel Arango

        Ok, i’ll be configuring the needed requirements and i’ll let you know. Thank you !

        • Awesome!

          • Manuel Arango

            Ok so, just to let any reader know… I use Netbeans, and it happens to ERASE every plugin when building the app; you may imagine the headache i’ve had. Thanks Nic, it was a very usefull tutorial.

          • Exactly the reason I don’t use an ide 😉

          • Miguel Ángel

            Sorry, how do you fix that?? I have the same error.

          • Manuel Arango

            Hi, sorry to reply so late, i edit the code on Netbeans but run it from cmd.

          • Miguel Ángel

            Don´t worry, which command do you use?? with “ionic server” I get the same “blank page with loading”. Tell me when you can, thank you so much

          • Manuel Arango

            Hi, I’m running the app on my android smartphone, there’s an ionic command wich let’s you see the plugins you have installed (dont remember wich one, ionic plugin something) you have to verify you have all the plugins before running your app, if not reinstall the plugins. In netbeans you can edit and save your code but don’t run it or your plugins will be deleted, then from cmd write “ionic run android” to run your app on your smartphone. Hope it can help you a little bit.

  • Hidayat

    Nic, thanks a lot for this nice tutorial.

    I am trying to create an Expense Tracker apps, and i am gonna create it use ionicframework and use SQLite as the database.

    I already success to following this tutorial, all running well when i test in web browser use : ionic serve.

    But, when i use : ionic run android ( i test on my android device ) , it still OK when first time i launch the app, but after i close the app and i run again, it’s show blank page. After i clear data in setting > apps > my_apps in Android setting, it’s normal again.

    Do you have any idea about this Nic ? I think there is problem in opening existing database, but i don’t know, honestly this is my first time use AngularJS and SQLite.

    I am really thank you for you help..

    Regards, Hidayat.

  • Bushra

    Hi Nic, First I want to thank you very much for your tutorials.

    Second could you help me with a question ?

    I want to get data from MySQL and store it in SQLite. I got tables through $http.get as json and fill the SQLite tables with responses .. but the problem is to get and save images ….

    Because In MySQL I uploaded images to the server and save them in columns as paths..

    Do you have any idea about How to download images from db and save it in my device ??

    I am really thank you for your help


  • iJorl

    Hello Nic

    I recently tried to insert some data in a pre-filled sqlite database. The DB has one table which has an ‘id’ (primary int etc.), an integer field named ‘key’ and some other fields which are only text.

    now when i want to insert a new record i get an error when i’m setting a value for my ‘key’ field. But if I only set my values for my text fields everything runs perfectly…

    Have you ever experienced a similar problem or do you know how to fix it?


    • Please share the error message and logs. Without them, I cannot help you.


      • iJorl

        Error Message:

        Object {message: “prepare statement failed with error: 1”, code: 0}

        Important Code:

        var query = “INSERT INTO todo (key,title, comment, date) VALUES (?,?,?,?)”;
        parameters = [1,”myTitle”,”myComment”,”myDate”];

        with these arguments i call a factory:

        $ionicPlatform.ready(function () {

        • Can you give me the DDL (create statement) for your todo table?

          • iJorl

            i created my db with the SQlite Browser tool …
            my old database seemed to be invalid for some reason so i created a new one with the same keys and now everything works just fine

            thanks for your pariance and help

          • Awesome! Glad you figured it out 🙂

  • Dhaval Koradiya

    hello nic,
    i have issue (see image.) when i run

    “cordova plugin add
    “cordova plugin add

    • Sounds like you have a configuration issue on your system. Unfortunately I am not a Windows user so I won’t be able to help you. I recommend you post in the forums.


    • Niklas

      Im working on windows, have you fix your problems….

      • Dhaval Koradiya

        No still not…

        • Niklas

          You need to add The Right PATH For git In your System configuration. …
          Mine is C:/program files/qit

    • Kudzie

      hi Dheval

      try reinstalling your git and choose the option to install comand line tools.

      i had the same problem but its now working perfectly

      • Dhaval Koradiya

        Thnak you for your reply.

    • You must install git. this is the link will help you to download git

  • Niklas

    Nice tutorials,
    I have follow this tutorials from top to bottom, I have watch the movie..
    I don´t get any errors.
    I can see anything…

    Can someone help me….

    • Dhaval Koradiya

      can you please help me with this error (image) ?

      • Niklas

        I work on a windows server 20122 r2, and i go to:
        control panel -> system
        Choose “Advanced system settings
        choose advanced in the tab, and Environment Variables
        System variables: mark PATH and then edit.
        in the end add ;
        I have C:Program FilesGitbin;
        try again if it work to install plugin

  • Niklas

    when i update the browser to see if the new categories is showing.
    I get: ReferenceError: db is not defined

    in this:

    // This is because we cannot try to query the database until our plugins are ready.
    $ionicPlatform.ready(function() {
    var query = “SELECT id, name FROM Category”;
    $cordovaSQLite.execute(db, query, []).then(function(res) {

    • I encourage you to not use the browser. You’re developing mobile applications, not web applications. The browser has no place in mobile application development.


      • Niklas

        I have try the android sdk.. But I never starts….
        can you recomend Something else. ..

        • What never starts?

          If the app builds and installs, find your logs using ADB. If the app never builds or installs, you have a configuration issue with your development environment.

          • Niklas

            ok, what does ADB means…

          • Android Debug Bridge

            It sounds like you are very new to mobile app development. Because of this I highly recommend you check out one of my beginner courses:


            It will probably resolve many of your development concerns as of now.


          • Niklas

            Im wery new to mobile app development.
            But i have manage to add your todo, I have add push.
            I can download it to my android and install it.

            But i can´t get it to work on the android SDK…

          • Niklas

            Like i said, its take to long for the android SDK to start.

  • maxpom

    Hello !

    There is a problem with no ?

    Because i have a problem when i try to install this plugin.

    “Failed to fetch plugin via git.

    Either there is a connection problems, or plugin spec is incorrect:


    • Looks like the developer changed the repo to:

      If you confirm that works, I will update my article.


    • Are you behind the proxy???
      the same problem occurred with me.

      but i solve this problem by the following proxy setting

      npm config set proxy url:port
      npm config set http-proxy url:port
      npm config set https-proxy url:port

      git config –system –add http.proxy url:port
      git config –global –add http.proxy url:port

      set proxy=url:port
      set http-proxy=url:port
      set htps-proxy=url:port

  • Azri Fared

    Hi Nic, thanks for the awesome tutorial.
    I have followed all the steps and it works for me,
    But I have a few questions regarding ionic run android command.
    At first when I run the command, the apps have error and I already fixed it.
    For the second time, I run the app using ionic serve and it work, but when I upload the apps on the real device, it seems like the apps is not updated and still running on the old code.
    can you help me with this problem?


    • Ionic Serve should never be used if you have plugins in your project. If building the APK and installing is not working, please provide your logs.


      • Azri Fared

        Thanks for the quick reply mate, I realized that ionic serve cannot compile $cordovaSQLite syntax well, just like you said. Now I’m using an Android device monitor to debug my code. My problem is the app is keep loading and below are the message in the console log. I still don’t understand why the app cannot run. Here is my source code

        • jimmy

          Hi, change the line “window.plugins.sqlDB.copy(“populated.db”, function() {” to “window.plugins.sqlDB.copy(“populated.db”, 0, function() {”



          This Method allows you the copy the database from www directory.

          window.plugins.sqlDB.copy(dbname, location, success,error);

          Here –

          dbname -> Is the name of the database you want to copy. The dbname can be filename (without extensions) or filename.db or filename.sqlite. The plugin will look for and copy the file according to the filename provided here. And the same file name should be used while opening the database via SQLitePlugin.

          location -> You can pass three integer arguments here (Use 0 for Android)-

          (for ios only)
          location = 0; // It will copy the database in the default SQLite Database directory. This is the default location for database
          location = 1; // If set will copy the database to Library folder instead of Documents folder.
          location = 2; // (Disable iCloud Backup) If set will copy the database to Library/LocalDatabase. The database will not be synced by the iCloud Backup.

          • Azri Fared

            Thanks a lot jimmiy, now my app can run 😀

      • Azri Fared

        This error only happens when I run using an emulator or real device, but work fine in web view

      • Azri Fared

        Hi nic, i already solve the problem,just some typing error mistake.

  • Richie Niclaus

    Hello Nic,

    I have followed all the steps and compile to apk but when i test it on android emulator all i can see is the ionic blank starter page,

    caught ReferenceError: require is not defined(anonymous function) @ splashscreen.js:22
    whitelist.js:23 No Content-Security-Policy meta tag found. Please add one when using the cordova-plugin-whitelist plugin.(anonymous function) @ whitelist.js:23

    Please advice where did it go wrong? im very new at this…

    Thank You

  • milan

    Uncaught TypeError: Cannot read property ‘sqlDB’ of undefined how to solve this issue

    • Can you give me your full logs? I also need more information than that. What are you trying to do?

  • Cathal Skelton

    HI, firstly thanks for the great tutorials, they have been a great help to a complete beginner. The issue I am having with the above and SQLite in general is storing the values of checkboxs, toggles etc, any boolean based item in fact. Any guidance on storing these types of values would be very much appericated.

  • Valerio

    Hi Nic, thanks for the awesome tutorial. Could you tell me where is db path?

    • The database is in the protected space of your device. After it is copied, it cannot be accessed without first rooting or jailbreaking your device.

      • Valerio

        Thank you for the swift reply. However, i’d like to know where is it created on workplace

        • Now I’m confused on what you’re referring to. Can you give me examples of what you’re after?

  • Nândâr Aung

    How can I get populated.db for this TodoApp

    • After the database is transferred to your device it is in protected storage. It cannot be accessed unless your device is jailbroken or rooted.

      If you’re asking how do you create the database, I’ve listed one of many tools that are suitable for the job.


      • Nândâr Aung

        I did as the toturials shown but can’t run as shown. 🙁

        • What’s not working? What do your logs say? I need more information, otherwise I can’t help you.


          • Nândâr Aung

            ReferenceError: require is not definedvar argscheck = require(‘cordova/argscheck’),

            ReferenceError: require is not defined
            var browser = require(‘cordova/platform’);
            ReferenceError: require is not defined
            var exec = require(‘cordova/exec’);

            ReferenceError: module is not defined

            module.exports = {

            uncaught exception: module cordova/confighelper not found

            ReferenceError: require is not defined
            var exec = require(‘cordova/exec’);

            Error: Module cordova-plugin-device.device does not exist.
            throw new Error(‘Module ‘ + moduleName + ‘ does not exist.’);

            deviceready has not fired after 5 seconds.cordova.js (line 1156)
            Channel not fired: onPluginsReadycordova.js (line 1149)
            Channel not fired: onCordovaReady

          • Why are you using require? Nowhere in my example do I do this.

          • Nândâr Aung

            Now I have the error that “Invalid apk file:adb install -r platforms/android/ant-build/CordovaApp-debug.apk” . What should I do?Pls help.

          • I see ant-build, but Apache Cordova hasn’t used Ant for ages. It uses Gradle. Based on everything you’ve shared so far, it looks like your environment is not correct. I recommend you take a look at the Ionic Framework documentation for installing / updating / configuring Apache Cordova and Ionic Framework.


  • Lolo

    Hi Nic,
    First, Thanks a lot for your site.

  • Lolo

    I’am a beginner, I followed all the steps. Could you tell me how can I do for run at the screen the 3 views ?

    • No idea what you’re talking about. Please try again. For future reference, one comment per response. When you post 3 comments it will send 3 emails to everyone else who commented.


  • Lolo

    There’s only 3 lines in index.html ? (it’s seems, on the video, this file is bigger). Thanks a lot.

    • The lines I included should be included in your index.html file, not replace.

  • Nândâr Aung

    I can’t run as shown in video,Pls help what I need,I attach screenshot.

  • Nândâr Aung

    Pls help this error,How to solve.

  • Nândâr Aung

    Please help me.I have this error and how to solve?

  • Nândâr Aung

    I have this error which I attach screenshot below.How to solve this error?Please help me.

    • You posted four comments within 1 hour asking for help on this article:

      You are not on my timezone. Your comments were 3am to 4am my timezone.
      I get a lot of comments every day and offer no expedited help

      You’ve been warned, but if it happens again, you won’t receive further help from me. Every time a comment is added it goes out via email to all 155 other people who have commented on this post. This creates spam.

      That said read this:


  • I Had visited the link as you commented in previous communication.
    the link is
    I tried the following commands

    This commands not work properly
    But the next commands is as follow and that doesn’t work and gives an error

    cordova plugin add
    cordova plugin add

  • Oliver Mensah

    Getting Syntax error for creating the tables on the terminal.
    This is the output.

    sqlite> CREATE TABLE tblCategories (


    category_name: TEXT


    Error: near “:INTEGER”: syntax error


    I need help in order to create the table and continue with the tutorials

    • I’ve not used the Terminal to create SQLite tables. If I had to guess, maybe you’re not suppose to be using colons ( : ) in your statements?

      You should use DB Browser for SQLite like I recommend in the tutorial.


  • Hallo nic, this article very help me, but i get problem, when i implement this article and i install apk on real device. the apllication can’t run. The apllication still display “Loading…”, but in my google chrome your article/source is running well. Can you tell me why in the code not running well on device ? Thank you a lot

  • OneLoud .

    Hi. I want to ask if we can create new DB instead of using the existing db file. As far as i understand in your tutorial is that you using populated.db which is an existing db, am i correct.
    I am planning to create new db so do i need to open my db first on top of the coding and change the “populated.db” to my new open db?

    • Well you could replace the copy logic with a few create statements to create the necessary tables.

  • busy

    Hello, Mr. Raboy, in the copying populated.db section, in which folder should I put the populated.db file, directly under www? and which folder would it be copied to?

  • matt downing

    Hi Nic, this tutorial work fine for me.

    I wonder. when I call db outside window.plugins.sqlDB.copy return null?
    second log is file already exists on the location, I don’t know the first log

    I/chromium( 3538): [INFO:CONSOLE(34)] “|||||->> $ionicPlatform.ready >>||null”,
    source: file:///android_asset/www/js/app.js (34)

    I/chromium( 3538): [INFO:CONSOLE(31)] “|||||->> window.plugins.sqlDB.copy Error

    || {“openargs”:{“name”:”populated.db”,”location”:”default”,”dblocation”:”nosyn
    c”},”dbname”:”populated.db”}”, source: file:///android_asset/www/js/app.js (31)

    window.plugins.sqlDB.copy(“populated.db”, 0, success, error(){
    console.log(“|||||->> window.plugins.sqlDB.copy Error >>|| ” + JSON.stringify(db));
    console.log(“|||||->> $ionicPlatform.ready >>||” + JSON.stringify(db));


    Hi my name is sk .md.basha without using database i done a pincode app.In this app develop in ionic frame work.but i dont know how to insert a search option in this app please give me a code and clear information

  • vishal

    Great tutorial