Question

I have this code:

html5DB.indexedDB.addSomething = function(foo) {
    var db = html5DB.indexedDB.db;
    var trans = db.transaction(["something"], "readwrite");
    var store = trans.objectStore("something");

    var isExisting = IsAlreadyExist(foo);
    // How to wait for that instruction to finish?

    if (!isExisting){
       var request = store.put({
           "text": foo,
           "timeStamp" : new Date().getTime()
       });
    }
};

I'm trying to understand how can I wait for the function IsAlreadyExist to finish. This function opens a cursor to iterate in the object store to determinate if a particular value exist.

Actually, there is no error, but I can't reach the code inside the if (!isExisting) because the value of the variable never changes.

This is the code of that second function:

function IsAlreadyExist(foo){
    var db = html5DB.indexedDB.db;
    var objectStore = db.transaction("something").objectStore("something");

    objectStore.openCursor().onsuccess = function(event) {
        var cursor = event.target.result;

        if (cursor) {
            if (cursor.value.text == foo)   
                return true;

            cursor.continue();
       }
    };

    return false;
}

Is there a way to wait for the end of the execution? Or maybe it is not a good way to proceed for checking if a value exist?

Was it helpful?

Solution

As IndexedDB is an asynchronous API you have to wait until operations are completed using callbacks.

First off we need to refactor the IsAlreadyExist method:

function IsAlreadyExist(foo, oncomplete) {
    var db = html5DB.indexedDB.db;
    var transaction = db.transaction("something");
    var objectStore = transaction.objectStore("something");

    var exists = false;

    objectStore.openCursor().onsuccess = function(event) {
        var cursor = event.target.result;

        if (cursor) {
            if (cursor.value.text == foo) {
                exists = true;
                return;
            }

            cursor.continue();
       }
    };

    transaction.oncomplete = function () {
        oncompleted(exists);
    };
}

Now we'll refactor your other method:

html5DB.indexedDB.addSomething = function(foo) {
    IsAlreadyExist(foo, function (isExisting) {
        if (!isExisting){
           var db = html5DB.indexedDB.db;
           var trans = db.transaction(["something"], "readwrite");
           var store = trans.objectStore("something");

           var request = store.put({
               "text": foo,
               "timeStamp" : new Date().getTime()
           });
        }
    });
};

So here you'll see we're passing the function to execute when the cursor search is done as a callback, which receives an argument of the status.

This can start getting a bit ugly, which is why Promise's are popular in JavaScript. I wrote a wrapper for IndexedDB that uses a Promise-based API called db.js.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top