MB34
MB34

Reputation: 4404

IndexedDB retrieving records with a promise

I am storing records in an IndexedDB. I need to write a function to get records and return them to in JSON format to a data grid. The values are also in JSON.

This code doesn't really work because of the asynchronous nature of the IndexedDB calls.

How can I rework this to better use of maybe a promise to get the data?

function getRecords(skip, take) {
    var transaction = db.transaction("docs", "readonly");
    var objectStore = transaction.objectStore("docs");
    var result = "";
    var request = objectStore.openCursor(IDBKeyRange.bound(skip,skip+take))
        .onsuccess = function(evt) {  
            var cursor = evt.target.result;  
            if (cursor) {  
                result = JSON.stringify(cursor.value) + ',';
                cursor.continue();
            }
            return result.substr(0, result.length-1);
        };
}

Called like this:

var recordData = '[' + getRecords(1,10) + ']';

Adding full code

<html>
    <head>
        <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
        <script type="text/javascript">
            var indexedDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB || window.msIndexedDB;
            var db;
            window.refreshing = false;
            var peopleData = [ 
                             {"FILENAME":"/NewDesigMemo1026732160521.pdf","DOC":"5/23/2016 | New Desig Memo","PRT_DT":"5/23/2016","EC":"","STATE":"","DES":"CC","PRG_CODE":"","DIST":"","CNAME":""},
                             {"FILENAME":"/NewDesigMemo1026732160521.pdf","DOC":"5/23/2016 | New Desig Memo","PRT_DT":"5/23/2016","EC":"","STATE":"","DES":"CSR","PRG_CODE":"","DIST":"","CNAME":""},
                             {"FILENAME":"/AttendanceOutOfStateMemo102673220160521.pdf","DOC":"5/23/2016 | Attendance Out of State Memo","PRT_DT":"5/23/2016","EC":"","STATE":"","DES":"CSR","PRG_CODE":"","DIST":"","CNAME":""},
                             {"FILENAME":"/Attend1026732160521.pdf","DOC":"5/23/2016 | Attendance","PRT_DT":"5/23/2016","EC":"","STATE":"","DES":"CM","PRG_CODE":"","DIST":"","CNAME":""},
                             {"FILENAME":"/NewMemo1026732160521.pdf","DOC":"5/23/2016 | New Desig Memo","PRT_DT":"5/23/2016","EC":"","STATE":"","DES":"CM","PRG_CODE":"","DIST":"","CNAME":""},
                            ];

            var peopleData2 = [ 
                              {"FILENAME":"/Attend102673220160312.pdf","PRT_DATE":"3/14/2016","EC":"","DOC":"3/14/2016 | CM Attendance","CRID":null,"PRG_CODE":"","STATE":"","DES":"","DATE_SENT":null,"PRG_DESC":null,"YEAR":null,"ISSUE":"","DIST":null,"CNAME":""},
                              {"FILENAME":"/RMagazine.aspx?I=r_spring_2016&P=1026732","PRT_DATE":"","EC":"","DOC":"R Magazine Spring 2016","CRID":null,"PRG_CODE":"","STATE":"","DES":"","DATE_SENT":null,"PRG_DESC":null,"YEAR":null,"ISSUE":"Spring 2016","DIST":null,"CNAME":""},
                              {"FILENAME":"/Packet+Notification+CSR+CC+20160309ALM.html","PRT_DATE":"3/9/2016","EC":"20160317LLM","DOC":"3/9/2016 | Packet Notification","CRID":null,"PRG_CODE":"","STATE":"","DES":"","DATE_SENT":null,"PRG_DESC":null,"YEAR":null,"ISSUE":"","DIST":null,"CNAME":"WTH"},
                              {"FILENAME":"Eval20160317LLM1026732.pdf","PRT_DATE":"","EC":"20160317LLM","DOC":"Evaluation_Packet","CRID":null,"PRG_CODE":"ALM","STATE":"LA","DES":"","DATE_SENT":null,"PRG_DESC":null,"YEAR":null,"ISSUE":"","DIST":null,"CNAME":"WTH"},
                              {"FILENAME":"Eval20160315LPR1026732.pdf","PRT_DATE":"","EC":"20160315LPR","DOC":"Evaluation_Packet","CRID":null,"PRG_CODE":"PR","STATE":"LA","DES":"","DATE_SENT":null,"PRG_DESC":null,"YEAR":null,"ISSUE":"","DIST":null,"CNAME":"IPR"}
                             ]
            function open() {
                var request = indexedDB.open("DocsDB");
                var upgraded = false;
                request.onupgradeneeded = function(evt) {
                    upgraded = true;
                    console.log("upgraded ok");
                    var dbnew = evt.target.result;

                    dbnew.onerror = function(event) {
                        console.log("IndexedDB error: " + evt.target.error.code);
                    };

                    var objectStore = dbnew.createObjectStore(
                             "docs", { keyPath: "id", autoIncrement: true });

                    objectStore.createIndex("docname", "DOC", { unique: false });
                    objectStore.createIndex("printdate", "PRT_DT", { unique: false });
                }
                request.onsuccess = function(evt) {
                    db = request.result;
                    if (!upgraded && !window.refreshing) {
                        throw "Not upgraded";
                    }
                    console.log("open ok");
                    request.result.onversionchange = function(e) {
                        if (e.newVersion === null) { // An attempt is made to delete the db
                            e.target.close(); // Manually close our connection to the db
                        }
                    };

                    if(typeof db != 'undefined' && !window.refreshing) {
                        var store = getObjectStore(db);                   
                        for (i in peopleData) {
                            store.add(peopleData[i]);
                            console.log("Added:"+peopleData[i]);
                        }
                    }
                }
                request.onerror = function() {
                    throw "Error in open";
                }
            }

             function getObjectStore(db, mode = 'readwrite') {
                 if(typeof db != 'undefined') {
                     var tx = db.transaction('docs', mode);
                     return tx.objectStore('docs');
                } else {
                    return null;
                }
             }

            function obliterate() {
                var request = indexedDB.deleteDatabase("DocsDB");
                request.onsuccess = function() {
                    console.log("delete ok");
                    open();
                }
                request.onerror = function(event) {
                    throw "Error in obliterate.";
                }
            }
            $(document).ready(function(){
                if(window.performance) { 
                    if(performance.navigation.type  == 0 ) {
                        // The db already exists so delete it and re-create it so we don't have stale records.
                        obliterate(); 
                    } else {
                        window.refreshing = true;
                        open();
                    }
                }

                $("#btnAdd").click(function () {
                    var transaction = db.transaction("docs", "readwrite");
                    var objectStore = transaction.objectStore("docs");
                    for (i in peopleData2) {
                        var request = objectStore.add(peopleData[i]);
                        request.onsuccess = function (evt) {
                            // do something after the add succeeded
                        };
                    }

                });

                $("#btnPrint").click(function () {                
                    window.finished = false;
                    var output = $("#printOutput");
                    getRecordsAsync( 1,10).then( data => {
                        output.html(data);
                    });
                });
            }); 

            function getRecordsAsync(skip, take) {
                return new Promise((resolve, reject) => {
                    var transaction = db.transaction("docs", "readonly");
                    var objectStore = transaction.objectStore("docs");
                    var result = "";
                    var request = objectStore.openCursor(IDBKeyRange.bound(skip,skip+take))
                        .onsuccess = function(evt) {  
                            var cursor = evt.target.result;  
                            if (cursor) {  
                                result = JSON.stringify(cursor.value) + ',';
                                cursor.continue();
                            }
                            resolve(result.substr(0, result.length-1));
                        }
                        .onerror = function(err) {
                          reject(err);
                        };
                });
            }


            function getRecords(output, skip, take, filter) {
                var transaction = db.transaction("docs", "readonly");
                var objectStore = transaction.objectStore("docs");
                var result = "";
                var range;
                if(filter != "" ) {
                    objectStore.index('docname');
                    range = IDBKeyRange.upperBound(filter);
                }
                range = IDBKeyRange.only(skip,skip+take)

                var request = objectStore.openCursor(range)
                    .onsuccess = function(evt) {  
                        var cursor = evt.target.result;  
                        if (cursor) {  
                            result = JSON.stringify(cursor.value) + ',';
                            cursor.continue();
                        }
                        window.finished = true;
                    };
            }

                    /*
                    var transaction = db.transaction("docs", "readonly");
                    var objectStore = transaction.objectStore("docs");
                    var result = "";
                    var range;
                    skip = 1;
                    take = 10;
                    range = IDBKeyRange.bound(skip,skip+take);
                    var request = objectStore.openCursor(range).onsuccess = function(evt) {  
                        var cursor = evt.target.result;  
                        if (cursor) {  
                            output.html( output.html()+"</br >id: " + cursor.key + " is: " + JSON.stringify(cursor.value)); // output.html(JSON.stringify(cursor.value));
                            cursor.continue();
                        }
                    };                      
                    */

        </script>
    </head>
    <body>
    <!-- http://localhost:8040/idb_test3.html -->
        <div id="container">
            <input type="button" id="btnAdd" value="Add Records" />
            <br />
            <br />
            <input type="button" id="btnPrint" value="Print objectStore" />
            <br />
            <br />
            <output id="printOutput">
            </output>
        </div>
    </body>
</html>

Upvotes: 4

Views: 4785

Answers (1)

Jeremy J Starcher
Jeremy J Starcher

Reputation: 23863

To promisify this code would be something like:

EDIT: Fixed stupid syntax error

function getRecordsAsync(skip, take) {
    return new Promise((resolve, reject) => {
        var transaction = db.transaction("docs", "readonly");
        var objectStore = transaction.objectStore("docs");
        var result = "";
        var request = objectStore.openCursor(IDBKeyRange.bound(skip, skip + take))
            .onsuccess = function(evt) {
                var cursor = evt.target.result;
                if (cursor) {
                    result = JSON.stringify(cursor.value) + ',';
                    cursor.continue();
                }
                resolve(result.substr(0, result.length - 1));
            }
            .onerror = function(err) {
                reject(err);
            };
    });
}


getRecordsAsync(1, 10).then(data => {
console.log(data);

EDIT

OK, I tracked down the error you were getting -- it was an uncaught rejection in the promise. I should have seen that myself.

This code catches the error properly.

I've tried to track down what the error is, but I wasn't getting anything useful out of the system and I don't know indexeddb at all.

            $("#btnPrint").click(function () {                
                window.finished = false;
                var output = $("#printOutput");
                getRecordsAsync(1,10).then( data => {
                    output.html(data);
                }).catch(err => {
                  console.log("There was an error calling getRecordsAsync");
                  console.log(event);
                });
            });

Upvotes: 4

Related Questions