I'm using CanJs and I'm learning jquery deferred but I have a problem. I created a controller as sort of Singleton to manage data in IndexedDb.
First of all, I created an openDb function like this:
openDbDeferred: null,
openDb: function (dbName, dbVersion) {
console.log('Open DB...');
var openDbDeferred = this.openDbDeferred;
if (!openDbDeferred || openDbDeferred.isRejected()) {
openDbDeferred = $.Deferred();
var db;
var req = indexedDB.open(dbName, dbVersion);
req.onsuccess = function (evt) {
db = this.result;
console.log('openDB SUCCESS');
openDbDeferred.resolve(db);
};
req.onerror = function (evt) {
console.error("[ERROR] openDb: " + evt);
openDbDeferred.reject();
};
req.onupgradeneeded = function (evt) {
console.log('openDb.onupgradeneeded');
var db = evt.target.result;
var store = db.createObjectStore('sessioni', {keyPath: 'idSession'});
store.createIndex('by_url', 'url', {unique: false});
store.createIndex('by_startDate', 'startDate', {unique: false});
store.createIndex('by_endDate', 'endDate', {unique: false});
};
}
return openDbDeferred.promise();
}
Then I created a function to retrieve all data in DB:
getFilesList: function () {
var getDataDeferred;
return this.openDb('session-db', 1).then(function (db) {
console.log('Find all records...');
getDataDeferred = $.Deferred();
var tx = db.transaction("sessioni", "readwrite");
var store = tx.objectStore("sessioni");
var items = [];
tx.oncomplete = function() {
//console.log(items);
getDataDeferred.resolve(items);
console.log('Transazione getFilesList completata');
};
tx.onfailure = function(evt) {
getDataDeferred.reject();
console.error('[ERROR] Transazione getFilesList fallita: ' + evt);
};
var cursorRequest = store.openCursor();
cursorRequest.onsuccess = function (evt) {
var cursor = evt.target.result;
if (cursor) {
items.push(cursor.value);
cursor.continue();
}
};
cursorRequest.onerror = function (error) {
console.error('findAll [ERROR]: ' + error);
};
});
return getDataDeferred.promise();
}
I declared this controller in another controller to call getFilesList function:
retreiveAllData: function() {
return this.sessionManageModel.getFilesList().than(function(items) {
console.log(items)
return items;
});
}
When the retreiveAllData function is called, it returns 'undefined' because items is 'undefined'.
How can I obtain items in retreiveAllData function?
You've got two return
statements in your getFilesList
function. The second one should actually be inside the then
callback - which currently returns undefined
as you observe.
getFilesList: function () {
// no need to declare deferred variable outside of the callback
return this.openDb('session-db', 1).then(function (db) {
var getDataDeferred = $.Deferred();
… // do all the stuff
return getDataDeferred; // place the `return` here
});
// not here!
}