EricF
EricF

Reputation: 301

from MySQL to IndexedDB

Good day, I'm not sure if my question is even something possible or not, that's why I ask :) I'm developping an app which uses PHP/MySQL when it's online, but uses indexedDB when offline (well, this is the target!). For the user, it's only to read the database (nothing to write on). When online, I'd like to populate the indexedDB database in order to be able to use it as soon as the app is offline with the content of the MySQL database.

What I want to do is something like that:

function checkNetwork() {
    if (!navigator.onLine) {
        console.log("Navigator is offline. Loading INDEXEDDB as is.");
        openIndexedDBDatabase();
    } else {
        console.log("Navigator is online. Loading database via PHP.");
        openPHPdatabase();
    }
}

I haven't figured how to populate the IndexedDB database... Here is an extract of the code I use to "try" to populate in the openPHPdatabase() function:

request.onsuccess = function (e) {

                    db = e.target.result;
                    var transaction = db.transaction("myDB", "readwrite");
                    var objectStore = transaction.objectStore("myDB");

                    console.log("Retrieve from PHP Database to indexedDB.");
                    $.getJSON('./php/database.php', function(data) {
                        $.each(data, function (key, value) {
                            //Populate here...
                        });
                    });
};

If you have any idea, I would be interested! :) Thanks in advance!

Upvotes: 3

Views: 2487

Answers (1)

Josh
Josh

Reputation: 18690

Well, for starters, you are mixing two async systems together (ajax and indexedDB), which will not always work. In order to guarantee that it will always work, you will need to rewrite the code so that you first fetch the json data, wait for it to complete, and then connect to the database, start a transaction, and execute put requests.

If you are familiar with promises, and you are also familiar with the new async functionality, and const/let, maybe something like this:

// Asynchronously open a connection to indexedDB
function openIndexedDBDatabase() {
 return new Promise(function(resolve, reject) {
   const request = indexedDB.open('dbname', dbversionnumber);
   request.onsuccess = () => resolve(request.result);
   request.onerror() = () => reject(request.error);
 });
}

// Asynchronously fetch some json data
function getJsonAsync(url) {
  return new Promise(function(resolve, reject) {
    $.getJSON(url, resolve);
  });
}

// Asynchronously store the data in indexedDB
function storeTheDataInIndexedDb(db, data) {
  return new Promise(function(resolve, reject) {
     const transaction = db.transaction('storename', 'readwrite');
     transaction.oncomplete = () => resolve();
     transaction.onerror = () => reject(transaction.error);
     const store = transaction.objectStore('storename');
     for(let obj of data) {
       store.put(obj);
     }
  });
}

// Asynchronously do all the things together
async function doStuff() {
   if(!navigator.onLine) {
      const data = await getJsonAsync('./php/database.php');
      const db = await openIndexedDBDatabase();
      await storeTheDataInIndexedDb(db, data);
      db.close();
   } else {
      openPHPdatabase();
   }
}

doStuff();

Upvotes: 2

Related Questions