Reputation: 2330
I am trying to use an index.openCursor(keyRange.only or keyRange.bound Provided here) to access one or more records using an index on a table created with autoIncrement: true. I have tried multiple variations with no success. Can someone show me a working example using the following code as a template:
window.indexedDB = window.indexedDB || window.webkitIndexedDB
|| window.mozIndexedDB || window.msIndexedDB;
var ixDb;
var ixDbIndexTest = function () {
//Open or create the requested IndexedDB Database
var ixDbRequest = window.indexedDB.open("testDBindexes", 2);
ixDbRequest.onupgradeneeded = function (e) {
ixDb = ixDbRequest.result || e.currentTarget.result;
objectStore =
ixDb.createObjectStore("demoOS",
{ keyPath: "id", autoIncrement: true });
objectStore.createIndex("ixdemo", "Field1",
{ unique: false, multiEntry: false });
//define new dummy record
var newRecord = {};
newRecord.Field1 = "222";
newRecord.Field2 = "333";
newRecord.Field3 = "444";
var request = objectStore.add(newRecord);
request.onsuccess = function (e) {
var index = objectStore.index('ixdemo');
var range = IDBKeyRange.only("222");
var cursorRequest = index.openCursor(range);
cursorRequest.onsuccess = function(e) {
var cursor = cursorRequest.result || e.result;
alert(cursor.value);
cursor.continue();
}
}
};
};
window.onload = ixDbIndexTest;
Update: I modified the demo script to work in both Firefox and older Chrome versions that still use setVersion. However, you would need to add additional version checking logic for Chrome since the current logic runs setVersion every time the script runs.
window.indexedDB = window.indexedDB || window.webkitIndexedDB
|| window.mozIndexedDB || window.msIndexedDB;
window.IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction
|| window.mozIDBTransaction || window.msIDBTransaction;
window.IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange ||
window.mozIDBKeyRange || window.msIDBKeyRange;
var ixDb;
var ixDbIndexTest = function () {
//Open or create the requested IndexedDB Database
var ixDbRequest = window.indexedDB.open("testDBindexes", 1);
ixDbRequest.onsuccess = function(e) {
ixDb = ixDbRequest.result || e.currentTarget.result;
if (typeof ixDb.setVersion === "function") {
ixDbVersionRequest = ixDb.setVersion(1);
ixDbVersionRequest.onsuccess = function (e) {
indexTest();
};
}
else {
ixDbRequest.onupgradeneeded = function (e) {
indexTest();
};
}
}
};
window.onload = ixDbIndexTest;
function indexTest() {
var objectStore = ixDb.createObjectStore("demoOS",
{ keyPath: "id", autoIncrement: true });
objectStore.createIndex("ixdemo", "Field1",
{ unique: false, multiEntry: false });
//define new record with users input
var newRecord = {};
newRecord.Field1 = "222";
newRecord.Field2 = "333";
newRecord.Field3 = "444";
var request = objectStore.add(newRecord);
request.onsuccess = function (e) {
var index = objectStore.index('ixdemo');
var range = IDBKeyRange.only("222");
var cursorRequest = index.openCursor();
cursorRequest.onsuccess = function(e) {
var cursor = cursorRequest.result || e.result;
if(cursor) {
alert(JSON.stringify(cursor.value));
cursor.continue();
}
}
}
}
Upvotes: 1
Views: 3974
Reputation: 9673
The error message Type Error: cursor is undefined
happens because you are using the cursor without checking to see if it's defined. So when cursor.continue()
tells IndexedDB to go get the next object in the database, the cursor will be undefined after it exhausts the only object that actually exists.
So you should do something like this. In your code, it would look like:
cursorRequest.onsuccess = function(e) {
var cursor = cursorRequest.result || e.result;
if (cursor) {
alert(cursor.value);
cursor.continue();
}
}
Also, if you know you are only looking for one object (like when you use IDBKeyRange.only
), you can just omit the cursor.continue()
part:
cursorRequest.onsuccess = function(e) {
var cursor = cursorRequest.result || e.result;
alert(cursor.value);
}
As for your problem With Chrome, I can't help you there as I've only focused on Firefox so far. I would recommend you try the latest development version of Chrome, which actually does support onupgradeneeded
along with various other updates, but in my testing so far it's still pretty buggy and code that works in Firefox can fail in Chrome. You might be better off just waiting some time for Chrome to stabilize, if this isn't an urgent project.
Upvotes: 4
Reputation: 13131
You cannot add records while in onupgardeneeded event.
after versing change, you must reopen the database to get new objectStore schema. so there will be two open
current chrome is, i think still old standard, setVersion, onupgardeneeded is never call.
newRecord must have keyPath 'id' or you should not specified keyPath in creating object store.
Upvotes: 0