I have following piece of SharePoint JavaScript client object code which works perfectly without throwing any error.
$(document).ready(function () {
//don't exectute any jsom until sp.js file has loaded.
SP.SOD.executeFunc('sp.js', 'SP.ClientContext', prepareTables);
});
function prepareTables() {
for (var i = 0; i < 3; i++) {
getItemsWithCaml('External User Account Request',
function (camlItems) {
var listItemEnumerator = camlItems.getEnumerator();
while (listItemEnumerator.moveNext()) {
var listItem = listItemEnumerator.get_current();
console.log(listItem.get_item('Title'));
}
},
function (sender, args) {
console.log('An error occured while retrieving list items:' + args.get_message());
});
}
}
function getItemsWithCaml(listTitle, success, error) {
var clientContext = new SP.ClientContext.get_current();
var list = clientContext.get_web().get_lists().getByTitle(listTitle);
var camlQuery = new SP.CamlQuery();
var camlItems = list.getItems(camlQuery);
clientContext.load(camlItems);
clientContext.executeQueryAsync(
function () {
success(camlItems);
},
error
);
};
However, if I replace the same code to use deferreds/promises I get collection has not been initialized error:
The collection has not been initialized. It has not been requested or the request has not been executed. It may need to be explicitly requested.
Following is the code using deferreds:
$(document).ready(function () {
//don't exectute any jsom until sp.js file has loaded.
SP.SOD.executeFunc('sp.js', 'SP.ClientContext', prepareTables);
});
function prepareTables() {
for (var i = 0; i < 3; i++) {
getItemsWithCaml('External User Account Request').then(
function (camlItems) {
var listItemEnumerator = camlItems.getEnumerator();
while (listItemEnumerator.moveNext()) {
var listItem = listItemEnumerator.get_current();
console.log(listItem.get_item('Title'));
}
},
function (sender, args) {
console.log('An error occured while retrieving list items:' + args.get_message());
}
);
}
}
function getItemsWithCaml(listTitle) {
//use of $.Deferred in the executeQueryAsync delegate allows the consumer of this method to write 'syncronous like' code
var deferred = $.Deferred();
var clientContext = new SP.ClientContext.get_current();
var list = clientContext.get_web().get_lists().getByTitle(listTitle);
var camlQuery = new SP.CamlQuery();
this.items = list.getItems(camlQuery);
clientContext.load(this.items);
clientContext.executeQueryAsync(
Function.createDelegate(this,
function () { deferred.resolve(this.items); }),
Function.createDelegate(this,
function (sender, args) { deferred.reject(sender, args); }));
return deferred.promise();
};
var listItemEnumerator = camlItems.getEnumerator();
throws error.this
changed in the delegate? Why not use avar items =
as you do in your first code snippet?