Reputation: 6698
I am using the idbKeyval library to save/retrieve data from IndexedDB local storage. I have a function to iterate through all my keys and get each corresponding object. However, when I retrieve each object (val
), I need to know its corresponding key (that is how I correlate the object with an element in the DOM). But since the IndexedDB (and idbKeyval) api is asynchronous, I lose reference to the corresponding key. Is there a way that I can retrieve the corresponding key
when I retrieve my val
? Below is a snippet that better describes what I am trying to do:
var customStore = new idbKeyval.Store('my-db', 'offline-transactions');
idbKeyval.keys(customStore)
.then(function (keys) {
for (var i in keys) {
var key = keys[i];
var val = idbKeyval.get(key, customStore)
.then(function (val) {
//THIS WORKS:
console.log(val);
//THIS DOES NOT WORK:
console.log(key);
//'KEY' IS OUT OF SCOPE HERE
//WHAT IS A GOOD WAY TO GET THE CORRESPONDING KEY FOR MY VAL HERE?
});
}
});
And I am using the idbKeyval library: https://github.com/jakearchibald/idb-keyval
Upvotes: 0
Views: 1012
Reputation: 1372
There are two three solutions to this. You can either create an IIFE (the old way) and set a local variable to "copy" the variable from your loop:
.then(function(val) {
(() => {
var localKey = key;
// ...
// localKey will be preserved since it's encapsulated
// in its own functional scope
})();
}
Or you can use the more elegant Array.forEach
ES6 method:
keys.forEach((key) => {
var val = // ...
// No need to copy key here since we're in a new functional
// scope by the nature of .forEach
});
Both methods essentially work the same -- you're preserving a variable by creating a new functional scope for each iteration of your loop.
Hope that helps clarify things a little.
EDIT
I missed the simplest* solution: using let
or const
in your for loop instead of var
. This works because let
and const
have block scope instead of function scope. This article helps explain that. So:
for (var i in keys) {
const key = keys[i];
// ...
// key will be preserved in block
}
Personally, I'd prefer Array.forEach
just because it looks simpler and protects you from ever having to worry about what scope you're in.
*Simplest: I had no idea until a moment ago.
Upvotes: 1