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.

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.