Search code examples
javascriptes6-promiseindexeddb

Array from recursive promises returns undefined


I am using Jake Archibald's indexedDB promise wrapper.

I have an object store that contains json objects and a separate auto incremented key. When I retrieve the objects i need to also get the key so i can later delete them.

I'm using iterateCursor to recursively step through the cursor so that i can directly add the key and value to an array which i return as a resolved promise.

static getThings(){

    return thingsDb.then(db => {
        let keyVals = [];

        const tx = db.transaction('things');
        const unsyncedStore = tx.objectStore('things');

        return unsyncedStore.iterateCursor(cursor => {
            if(!cursor) return Promise.resolve(keyVals);
            console.log(`key: ${cursor.primaryKey}, val: ${cursor.value}`);
            keyVals.push({key: cursor.primaryKey, value: cursor.value});
            cursor.continue();
        });
    }).catch(error => {
        console.error(error);
    });

}

however when I call

DBHelper.getThings().then(returnedArray=> {
  // do something with returnedArray
})

it throws an error saying the returned array is undefined.


Solution

  • iterateCursor doesn't return anything (i.e. returns undefined)

    You need to return the promise available at unsyncedStore.complete

    But this promise won't resolve to a useful value, so, use .then to return the keyVals

    Also, no point in doing if(!cursor) return Promise.resolve(keyVals); since the return value from the iterateCursor callback is ignored

    static getThings() {
        return thingsDb.then(db => {
            let keyVals = [];
    
            const tx = db.transaction('things');
            const unsyncedStore = tx.objectStore('things');
            // no return here since iterateCursor doesn't return anything useful anyway   
            unsyncedStore.iterateCursor(cursor => {
                if (!cursor) return;
                console.log(`key: ${cursor.primaryKey}, val: ${cursor.value}`);
                keyVals.push({key: cursor.primaryKey, value: cursor.value});
                cursor.continue();
            });
            // return here - complete is a promise that resolves when the iterateCursor completes
            return unsyncedStore.complete.then(() => keyVals);
        }).catch(error => {
            console.error(error);
        });
    }