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:
1 Answer
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.