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
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 :)
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.