webcss / angular-indexedDB

An angularjs serviceprovider to utilize indexedDB with angular
149 stars 99 forks source link

onsuccess vs oncomplete #10

Closed jzumbrun closed 1 year ago

jzumbrun commented 10 years ago

It seems in indexdDB if a write transaction is started but not completed before a read transaction is started, the read transaction will not contain the new data the right transaction creates. I can confirm this by calling insert(), then within its promise.then() call a getAll(), the getAll() results do NOT contain the newly inserted data. See http://stackoverflow.com/questions/16424897/onsuccess-and-oncomplete-call-back-is-not-working-for-indexeddb-add-transaction

My work around was to pass an option to insert(), ie insert({my_object}, true), where true will resolve the $q within this.transaction.complete instead of just within req.onsuccess():

"insert": function(data, oncomplete){
    var d = $q.defer();
    return this.internalObjectStore(this.storeName, READWRITE).then(function(store){
        var req;
        if (angular.isArray(data)) {
            data.forEach(function(item){
                req = store.add(item);
                req.onsuccess = req.onerror = function(e) {
                    $rootScope.$apply(function(){
                        d.resolve(e.target.result);
                    });
                };
            });
        } else {
            req = store.add(data);
            req.onsuccess = req.onerror = function(e) {

                if(oncomplete === true){
                    this.transaction.oncomplete = function(){
                        console.log('Insert transaction completed.');

                        $rootScope.$apply(function(){
                            d.resolve(e.target.result);
                        });
                    };
                }
                else{
                    $rootScope.$apply(function(){
                        d.resolve(e.target.result);
                    });
                }
            };
        }
        return d.promise;
    });
},

The only other way to make this work is to use the same transaction call that is suggested via the stackoverflow link above.

Either way the update and delete calls should probably have something similar, or these methods should by default always resolve their promises in their respective oncompletes instead of just onsuccess. Please let me know if there is another way to solve this. Thanks

webcss commented 10 years ago

This is due to the nature of promises which resolve only once, when there's a result (success or error). They don't pass thru following resultsets. IF You use pure firebase with callbacks everything works as exspected, since the callback will be called anytime new data arrives. A workaround would be to modify promises not to expire once they're fullfilled.