Reputation: 119
How to wait for a an AJAX response in IndexedDB to finish. I have the bellow code and if I run it async the second transaction links all responses to the last item from the first response. I'd liek to populate both stores of reports&receipts from the server on login so I can then work offline if needed. If I make it synchornous it works correctly but it is bad from user experience side as the app freezes a bit so I'd like to avoid that. Has anyone got a suggestion?
var DBRequest = window.indexedDB.open(IDBName, IDBVersion);
DBRequest.onerror = function(event) {
console.log("error: ");
};
DBRequest.onsuccess = function(event) {
var response = DBRequest.result;
SExpenses.removeAll();
var z=0;
Ext.Ajax.request({
url:App.url.expenses,
method: 'GET',
async:true,
params: {
user_guid: App.user.guid,
limit: 25
},
success: function(res){
var result = Ext.decode(res.responseText);
var dataIDB = response.transaction(["ReportDataLocal"],'readwrite').objectStore("ReportDataLocal");
dataIDB.clear();
var receiptIDB = response.transaction(["ReceiptsLocal"],'readwrite').objectStore("ReceiptsLocal");
receiptIDB.clear();
var savedID, savedRecID;
Ext.each(result.data, function(item){
z++;
SExpenses.insert(0,item);
var newObject = response.transaction(["ReportDataLocal"], "readwrite")
.objectStore("ReportDataLocal")
.add({DESCRIPTION: item.DESCRIPTION, BILLING_QTY: item.BILLING_QTY,
TRAVEL_EXPENSES: item.TRAVEL_EXPENSES,REQUEST_TYPE_ID: item.REQUEST_TYPE_ID,
SERVER_ID: item.SERVER_ID
});
newObject.onsuccess = function(event){
savedID = event.target.result;
SExpenses.findRecord('SERVER_ID',item.SERVER_ID).set({ID:savedID});
Ext.Ajax.request({
url: App.url.receipts,
async: true,
method: 'GET',
params: {
Request_Log_RC: item.SERVER_ID
},
success: function(retrieve){
var result2 = Ext.decode(retrieve.responseText);
Ext.each(result2.data,function(item2){
SReceipt.add(item2);
var newReceiptIDB = response.transaction(["ReceiptsLocal"],'readwrite')
.objectStore("ReceiptsLocal");
newReceiptIDB.add({EXPENSE_AMOUNT: item2.EXPENSE_AMOUNT, EXPENSE_CURRENCY_ID:item2.EXPENSE_CURRENCY_ID,
EXPENSE_NAME: item2.EXPENSE_NAME, REPORT_ID: savedID, CURRENCY_ABB: item2.CURRENCY_ABB,
EXPENSE_IMAGE: null, SYNCED: true, DELETED: item2.DELETED,
SERVER_ID: item2.SERVER_ID, SERVER_REPORT_ID: item.SERVER_ID,
EXPENSE_EXCHANGE_RATE: null
});
newReceiptIDB.onsuccess = function(event){
savedRecID = event.target.result;
SReceipt.findRecord('SERVER_ID',item2.SERVER_ID).set({ID:savedRecID});
};
});
}
});
};
});
}
});
};
Upvotes: 0
Views: 278
Reputation: 973
So what you need to do is bind the item, https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind
Basically if you ever do an async call looping over multiple items and you need the callback to keep the index of the original call you bind the index and pass it in.
var returnData = [];
var a = 10;
for(var i = 0; i < a.length; i++) {
someAysncCall(function(data){
returnData[i] = data;
}).bind(null, i);
}
This will keep the i in the scope of the callback.
Looks like from your code you want item to stay in context so if you add bind to this
newObject.onsuccess = function(event){
savedID = event.target.result;
SExpenses.findRecord('SERVER_ID',item.SERVER_ID).set({ID:savedID});
Ext.Ajax.request({
url: App.url.receipts,
async: true,
method: 'GET',
params: {
Request_Log_RC: item.SERVER_ID
},
success: function(retrieve){
var result2 = Ext.decode(retrieve.responseText);
Ext.each(result2.data,function(item2){
SReceipt.add(item2);
var newReceiptIDB = response.transaction(["ReceiptsLocal"],'readwrite')
.objectStore("ReceiptsLocal");
newReceiptIDB.add({EXPENSE_AMOUNT: item2.EXPENSE_AMOUNT, EXPENSE_CURRENCY_ID:item2.EXPENSE_CURRENCY_ID,
EXPENSE_NAME: item2.EXPENSE_NAME, REPORT_ID: savedID, CURRENCY_ABB: item2.CURRENCY_ABB,
EXPENSE_IMAGE: null, SYNCED: true, DELETED: item2.DELETED,
SERVER_ID: item2.SERVER_ID, SERVER_REPORT_ID: item.SERVER_ID,
EXPENSE_EXCHANGE_RATE: null
});
newReceiptIDB.onsuccess = function(event){
savedRecID = event.target.result;
SReceipt.findRecord('SERVER_ID',item2.SERVER_ID).set({ID:savedRecID});
};
});
}
});
}.bind(null, item);
It should work
Upvotes: 1