bramski / angular-indexedDB

An angularjs serviceprovider to utilize indexedDB with angular
165 stars 49 forks source link

Difference between .getAll() and .each()? #85

Open itjustwerks opened 5 years ago

itjustwerks commented 5 years ago

Can someone explain the difference between these 2 methods? They both seem to return an array of all items in the object store. For a very large set of records, I was hoping for a way to iterate through them in a way that didn't require them all being held in memory at the same time, which is what I though .each() would do. Any ideas?

itjustwerks commented 5 years ago

Or maybe I just don't know how to properly use the .each() method...

bramski commented 5 years ago

.each() or .eachWhere is what you want. .getAll() fetches all records and returns them as an array.

itjustwerks commented 5 years ago

Oh...I guess the syntax is

$indexedDB.openStore('storeName', function(store) {
   store.each(function(item) {
      // do synchronous stuff with item
   });
});

I was calling

store.each().then(function(items){
   // items is the entire object store array...
});

My bad!

itjustwerks commented 5 years ago

What if I need to do async stuff within the .each loop? Specifically, changing and upserting the modified records as I go.

$indexedDB.openStore('storeName', function(store) {
   store.each(function(item) {
      item.property = 'changed';
      store.upsert(item).then(function() {
         // Go to the next item in the store...
      });
   });
});
bramski commented 5 years ago

Yes that is the idea. When you open the store you get a transaction so you should launch all your tasks there. I honestly haven't touched this codebase in quite a few years so I hope that all works!

itjustwerks commented 5 years ago

So getting back to this and digging in a bit more, I'm able to attach to the $q.notify events for the .each() function as follows:

$indexedDB.openStore('storeName', function(store) {
   store.each().then(function(allData){
      // all records have been iterated...
   },function(error){
      // an error occurred...
   },function(item) {
      // updates are notified here via the native store.openCursor().onsuccess function
   });
}).then(function() {
   // transaction is complete
});

I'm still stuck on how to do anything asynchronously within that loop. In my use case, many of the records are dependent on each other, and updates made to one record need to be saved back to indexedDb to be available when other records are processed. Is it possible to do async jobs within the openCursor lifecycle in IndexedDB?