Question

I'm trying to take the values of a certain key from an indexed DB and add them to an array, this array works fine within the onsuccess function but is empty after it. I'm guessing by the order the two years[0] that are logged to the console appear that problem is something to do with being asynchronous. I'm obviously not really understanding what order things are happening in and how to achieve what I want. Could someone please help me understand what the problem is and maybe point me in the right direction to overcoming it.

// the array I want the values in
var years = new Array(); 

// function retrieves all objects between certain years, low and high
function getYears(low, high){  

var request = window.indexedDB.open("matchDB", 1);  
request.onerror = function(event) {console.log("onerror");}

request.onsuccess = function(event) {
var db = event.target.result;
var objectStore = db.transaction(["matches"], 'readonly').objectStore("matches");

var index = objectStore.index("year");
var range = IDBKeyRange.bound(low, high, true, true); 

var request = index.openCursor(range);
  request.onsuccess = function(evt) {
     var cursor = evt.target.result;
     if (cursor) {
        var matchList = cursor.value;
        // the value of the key year is pushed into the array years
        years.push(matchList.year);
        console.log(years[0]); // this works
        cursor.continue();
     }
  }
console.log(years[0]); //this is undefined
}
}
Was it helpful?

Solution

request.onsuccess is a callback function that will get called when the asynchronous request has completed. Notice that you are just assigning a function to the onsuccess property, you are not executing the function. It could be executed seconds later.

The code following it will continue to be executed after it has been defined, so console.log(years[0]) will be called immediately after which is why it prints out "undefined" since the callback method hasn't been executed yet. All of your code that deals with "years" should go inside the callback.

If you don't want to shove all of your code inside the callback, just define another method and call it from within the callback method.

function handleRequest(evt) {
    var cursor = evt.target.result;
     if (cursor) {
        var matchList = cursor.value;
        // the value of the key year is pushed into the array years
        years.push(matchList.year);
        console.log(years[0]); // this works
        cursor.continue();
     }
}

var request = index.openCursor(range);
  request.onsuccess = function(evt) {
     handleRequest(evt);
  }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top