Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to return indexedDB query result out of event handler?

I have to return query result from indexedDB, but the result is only available in onsuccess event handler.

1  function listPeople(){
     ...
4    var open = indexedDB.open("AccordionDatabase",1),
5        res;
6
7    open.onsuccess = function(){
8        var db = open.result;
9        var transaction = db.transaction("PeopleStore", "readwrite");
10        var store = transaction.objectStore("PeopleStore");
11        var request = store.getAll();
12        request.onsuccess = function(event){
13            res = event.target.result;
14            console.log(res);
15        };
16
17        // Close the db when the transaction is done
18        transaction.oncomplete = function() {
19            db.close();
20        };
21
22    };
23    return res;
24 }

The output of the function call shows undefined, though console prints the result array. Please guide me how to use the variable as output.

like image 595
Miron Avatar asked Oct 23 '25 05:10

Miron


1 Answers

you can either use this project: https://github.com/jakearchibald/idb

or you need to wrap indexedDB operation into a promise and thus make the list people asynchronous:

function listPeople() {
// ...
  return new Promise(function (resolve, reject) {
    var open = indexedDB.open("AccordionDatabase",1),
    open.onsuccess = function() {
      var db = open.result;
      var transaction = db.transaction("PeopleStore", "readwrite");
      var store = transaction.objectStore("PeopleStore");
      var request = store.getAll();
      request.onsuccess = function(event){
        resolve(event.target.result);
      };

      request.onerror = function(event) { reject(event) }

      // Close the db when the transaction is done
      transaction.oncomplete = function() {
        db.close();
      };
      transaction.onerror = function(event) { reject(event) }
    };
    open.onerror = function(event) { reject(event) }
  })
}

// usage:
function doWorkWithListedPeople(people) {
  // ...
}

function handleErrorsDuringIndexedDbRequest(event) {
  // ...
}

listPeople().then(doWorkWithListedPeople).catch(handleErrorsDuringIndexedDbRequest)

// or also
listPeople().then(function(people) { doWorkWithListedPeople(people) })

The thing is, you create a promise that represents work that will be eventually done. You can tell JS that eventually, when the promise has been resolved (success), you want to then to work with anything that has been passed to resolve. See https://developer.mozilla.org/cs/docs/Web/JavaScript/Reference/Global_Objects/Promise and https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function for details


EDIT

furthermore, if you don't like thens, you can make do with async await, which unwraps promises. Just beware, you can only use await keyword from within async function:

async function doStuff() {
  try {
    var people = await listPeople()
    // now you can work with ppl
  }
  catch (err) {
    // handle listPeople errors here
  }
}
like image 141
netchkin Avatar answered Oct 24 '25 21:10

netchkin



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!