An Asynchronous Task List in Apache Cordova

I’ve been spending a bunch of time recently learning Apache Cordova with an eye towards integrating something within Azure Mobile Apps. I want to have an iOS and Android app that works with my TodoItem backend in Node. I also want it to be written in ES2015. So far, I’ve done a bunch of the basic work, but now it’s time to put an app together. You can see most of the work on my GitHub repository.

What I want to consider today is an asynchronous task list store. Each task in the TodoItem has an ID (which is a GUID converted to a string), a text description and a completed flag. I need to be able to read, insert and update records. I’m not going to deal with deletions right now, but that’s coming. To abstract this, I’m going to write an ES2015 class. Let’s start with the basics:

import uuid from 'uuid';

export default class Store {
    constructor() {'Initializing Storage Manager');
        this._data = [
            { id: uuid.v1(), text: 'Item 1', complete: false },
            { id: uuid.v1(), text: 'Item 2', complete: false }

I’m creating two example tasks to get me started. I don’t need them, but it helps to show off the HTML coding.

At the center of asynchronous programming in JavaScript is the Promise. Put simply, a promise is a representation of something that doesn’t exist yet. It will be asynchronously resolved and your code can come back to it later. You can use promises relatively simply:

   .then((result) => {
      /* do something with the result */
   }).catch((error) => {
      /* do something with the error */

You can chain multiple promises and wait for multiple promises to complete. This all results in a rather flexible mechanism to make your code asynchronous. But how do you create a promise? My Store class has an array right now. I want to make it ACT asynchronously so that I can add the network code later on. You need to write a method that either resolves or rejects the promise. Here is the insert() method:

     * Insert a new object into the database.
     * @method insert
     * @param {object} data the data to insert
     * @return {Promise} - resolve(newitem), reject(error)
    insert(data) { = uuid.v1();
        console.log('[storage-manager] insert data=', data);
        var promise = new Promise((resolve, reject) => {
            // This promise always resolves
        return promise;

Creating a promise is a case of creating a new Promise object with a callback function. The callback will be passed “what to call when you are resolving or rejecting the promise”. You then do your processing and call the resolve or reject method to say “I’m done”. Note that I’m using “fat-arrows” to preserve the this variable value. If you don’t use a fat-arrow function then you have to preserve this by other means. All my other functions are similar. For example:

     * Read some records based on the query.  The elements must match
     * the query
     * @method read
     * @param {object} query the things to match
     * @return {Promise} - resolve(items), reject(error)
    read(query) {
        console.log('[storage-manager] read query=', query);
        var promise = new Promise((resolve, reject) => {
            var filteredData = this._data.filter((element, index, array) => {
                for (let q in query) {
                    if (query[q] !== element[q]) {
                        return false;
                return true;
        return promise;

This will return a list of tasks that match my criteria.

Using this class is encapsulated in my index.js code:

app.on('deviceready', function () {
    var taskStore = new Store();
    // Get the various pieces of the UX so they can be referred to later
    var el = {
        todoitems: document.querySelector('#todo-items'),
        summary: document.querySelector('#summary'),
        refreshlist: document.querySelector('#refresh-tasks'),
        addnewtask: document.querySelector('#add-new-task'),
        newitemtextbox: document.querySelector('#new-item-text')
    // This is called whenever we want to refresh the contents from the database
    function refreshTaskList() {
      el.summary.innerHTML = 'Loading...';
      console.log('taskStore = ', taskStore);{ complete: false }).then((todoItems) => {
          console.log('Read the taskStore: items = ', todoItems);
          let count = 0;
          el.todoitems.innerHTML = ''; 
          todoItems.forEach((entry, index) => {
              let checked = entry.complete ? ' checked="checked"': '';
              let entrytext = entry.text.replace('"', '"');
              let html = `<li data-todoitem-id="${}"><input type="checkbox" class="item-complete"${checked}><div><input class="item-text" value="${entrytext}"></div></li>`;
              el.todoitems.innerHTML += html;
          el.summary.innerHTML = `<strong>${count}</strong> item(s)`;  
      }).catch((error) => {
          console.error('Error reading task store: ', error);
          el.summary.innerHTML = '<strong>Error reading store.</strong>';

    // Set up the event handler for clicking on Refresh Tasks
    el.refreshlist.addEventListener('click', refreshTaskList);

Note the highlighted line. I call the read() method (above) and wait for it to return the value. This can be asynchronously. Once it completes, the results are passed into the fat-arrow function in the then clause and that renders the list of tasks for me.

The changes to this version are quite extensive, so I encourage you to check out the code at my GitHub Repository. All the ES2015 code is in src/js with the store implementation in src/js/lib/storage-manager.js.

I still have some work to do here. Specifically, I copied (and updated) the Azure Mobile Services Quick Start for Apache Cordova and ES2015. I want to update the CSS3 code to be a little more friendly towards the devices. I also want to implement sorting and filtering. That’s the topic for another blog post.