0

I am having a challenge with indexedDB keys not matching the record numbers. To correct this I need to cycle through the records and reset the ID to match the index. I am trying to form an array that contains all the record IDs with a cursor, but it returns immediately.

How can I wait until all ids have been gathered before returning the array?

So far I have this.

async function getKeyIndex(s) {
    var i = await countDBRecords(s);   // my own f() - no problem here.
    var dbStore = [];
    var c = 0;
    var objectStore = db.transaction(s).objectStore(s);
    objectStore.openCursor().onsuccess = event => {
        var cursor = event.target.result; 
        if (cursor) {
            console.log("Name: " + cursor.key + " - id: " cursor.value.id);
            dbStore[c]= cursor.value.id;
            c++;
            if(c<i){cursor.continue();}
            else{return(dbStore)};
        } 
    };
}

Fired by:

        keyIndex = await getKeyIndex('conversations');
        console.log("Database keys " + keyIndex);

But the function always returns an undefined value as the onsuccess events have yet to complete before the function ends.

How can I keep the function from returning the array before it is populated?

7
  • 3
    The return statement is for the inner function you assign to .onsuccess, not the outer getKeyIndex function. Return a Promise from the outer function that gets resolved in the .onsuccess handler. Commented Oct 17 at 12:06
  • @Jared Smith That would only return one item at a time, rather than the whole array. Commented Oct 17 at 12:08
  • 2
    No, you would not resolve the promise until the point where you currently have the return statement. Commented Oct 17 at 12:09
  • 2
    Pointy is correct: since you resolve the returned Promise yourself just don't resolve it until the data is populated. Also the indexeddb API is... not what I'd call good. Don't be afraid to explore a wrapper like dexie. Commented Oct 17 at 12:13
  • 1
    I've removed the solution from the question. Post it as an Answer below. Commented Oct 17 at 14:32

1 Answer 1

1

SOLVED - Thank you to hints from Jared Smith and Pointy in the comments.

async function getKeyIndex(storeName) {
    return new Promise((resolve, reject) => {
        const dbStore = [];
        let c = 0;
        const objectStore = db.transaction(storeName).objectStore(storeName);
        const cursorRequest = objectStore.openCursor();

        cursorRequest.onsuccess = (event) => {
            const cursor = event.target.result;
            if (cursor) {
                console.log("Name: " + cursor.key + " - id: " + cursor.value.id);
                dbStore.push(cursor.value.id);
                c++;
                cursor.continue();
            } else {
                resolve(dbStore);
            }
        };
    });
}

Fired by:

        keyIndex = await getKeyIndex('conversations');
        console.log("Database keys " + keyIndex);
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.