I have an uploadList
object populated by the code in block 2, but when I step through this code I will intermittently see the return uploadList
line reached before the issueRepository.GetIssuesOffline
function. This means that when I later loop through the uploadList
(as per block 1), the r.amount
, r.returns
, and r.barcode
are NULL, as they have not been set yet (the u.issue
is undefined).
If I put a setTimeout
on the call to Block 1 the code seems to execute all the way through if I give it long enough to process, but without a SetTimeout
the uploadList
looks almost like it is returning asynchronously before waiting for all the previous functions to complete.
Can anyone see what I am missing here, and understand why the issue object would not be defined in the processIssues
function before block 2 completes and returns?
Block 1:
var returns = Enumerable
.From(uploadList)
.Select(function (u) {
var i = u.issue();
var r = i.Returns();
return {
amount: r.amount,
Totes: r.totes,
barcode: r.barcode,
Depo: i.supplier == null ? 'Unknown supplier' : i.supplier.name,
StatusID: i.Status.Code,
SupplierID: i.supplier.id,
DepoFullName: i.depot
}
})
.ToArray();
Block 2:
me.getIssuesFromReturnsList = function () {
var uploadList = [];
$.each(me.returnsList(), function (index, i) {
var issue = issueRepository.GetDefaultIssue();
issue.productname = "Loading from server...";
issue.barcode = i.barcode;
issue.ReturnsAmount(i.amount);
var uploadItem = {
barcode: i.barcode,
amount: i.amount,
issue: ko.observable(issue)
};
uploadList.push(uploadItem);
issueRepository.GetIssuesOffline(i.barcode, function (issues) {
if (issues.length > 0) {
uploadItem.issue(issues[0]);
}
});
});
return uploadList;
}
Code behind some of these functions for reference is as follows:
GetIssuesOffline:
GetIssuesOffline: function (barcode, callback) {
var me = this;
issueDatabase.GetIssues(barcode, function (issues) {
me._processIssues(issues);
return callback(issues);
});
}
issueDatabase.getIssues:
GetIssues: function (barcode, callback) {
var me = this;
db.transaction(
function (context) {
var query = "SELECT * FROM issues WHERE barcode LIKE '" + barcode + "%' ORDER BY offSaleDate DESC LIMIT 25";
context.executeSql(query, [], function (context, result) {
var issues = [];
for (var i = 0; i < result.rows.length; i++) {
var issue = result.rows.item(i);
issue.Source = dataSources.Local;
issue.isRanged = issue.isRanged == 1 ? true : false;
issues.push(issue);
}
callback(issues);
}, me.ErrorHandler);
}
, me.ErrorHandler);
}
me.processIssues:
_processIssues: function (issues) {
var me = this;
$.each(issues, function (index, i) {
if (i.issueNumber == null) {
i.issueNumber = '';
}
i.issueNumber = i.issueNumber + '';
i.productNumber = i.productNumber + '';
if (i.issueNumber.length == 1) {
i.issueNumber = '0' + i.issueNumber;
}
i.barcode = parseInt(i.productNumber + '' + i.issueNumber);
i.Status = me.GetIssueStatus(i);
i.supplier = me.GetissueSupplierDetails(i);
i.ReturnsAmount = ko.observable(0);
i.Returns = ko.observable({ totes: [] });
returnsRepository.GetReturn(i.barcode, function (r) {
i.ReturnsAmount(r.amount);
if (r.amount > 0) {
i.Returns(r);
} else {
i.Returns({ totes: [] });
}
});
};
i.RefreshReturnsAmount();
me.IssueDatabase.UpdateIssue(i, function (issue) {
me.IssueDatabase.UpdateIssueLastUpdated(issue);
});
});
}