Running code only after an object is updated in IndexedDB (particularly in Chrome)

前端 未结 2 1699
心在旅途
心在旅途 2020-12-21 07:58

I feel like this is a pretty mundane thing to do. I want to update an object in an IndexedDB database and then run some code after which uses the updated values.

Wha

相关标签:
2条回答
  • 2020-12-21 08:27

    I used the promise pattern to avoid the settimeout and JayData library to unify the data access and hide cursor API. After including the library (include.jaydata.org/jaydata.min.js) the snippet looks like this (online jsfiddle):

    $data.Entity.extend("Todo", {
        Id: { type: "int", key: true, computed: true },
        Task: { type: String, required: true, maxLength: 200 }
    });
    
    $data.EntityContext.extend("TodoDatabase", {
        Todos: { type: $data.EntitySet, elementType: Todo }
    });
    
    var todoDB = new TodoDatabase({ 
        provider: 'indexedDb', databaseName: 'MyTodoDatabase'
    });
    
    todoDB.onReady(function() {
        var newTodo = new Todo({Task: "alma"});
        todoDB.Todos.add(newTodo);
        todoDB.saveChanges()
        .then(function() {
            console.log("Initial value: ", newTodo.Task);
            todoDB.Todos.attach(newTodo);
            newTodo.Task = "korte";
            return todoDB.Todos.saveChanges();
        })
        .then(function(){
            console.log("Updated value: ", newTodo.Task);
            return todoDB.Todos
            .filter(function(t) {return t.Id == item.Id;}, {item: newTodo})
            .toArray(function(dbResult){
                var todoFromDb = dbResult[0];
                console.log("Value from DB: ", todoFromDb.Task);
            });
        })
    
    
    });
    

    It's much less code and you only have to change the type of the provider to change to WebSQL :)

    0 讨论(0)
  • 2020-12-21 08:48

    You don't need setTimeout, just wait transaction to complete as follow:

    // Update data
    var tx = db.transaction("objects", "readwrite");
    
    tx.objectStore("objects").openCursor(0).onsuccess = function (event) {
        var cursor, object;
    
        cursor = event.target.result;
        object = cursor.value;
        object.value = 43;
        cursor.update(object).onsuccess = function (event) {
            db.transaction("objects").objectStore("objects").get(0).onsuccess = function (event) {
                console.log("Cursor update onsuccess event:");
                console.log(event.target.result);
            };
        };
    
    };
    
    tx.oncomplete = function() {     
        // Read back updated data
        db.transaction("objects").objectStore("objects").get(0).onsuccess = function (event) {
            console.log("The line after the cursor update:");
            console.log(event.target.result);
       };
     }
    

    This is one of the confusing aspect of IndexedDB API. Request onsuccess don't not mean your success is written to the database. Only transaction oncomplete confirm it. The reason is, you can still abort transaction tx.abort() after write request.

    0 讨论(0)
提交回复
热议问题