How to return results from executeQueryAsync
-
08-02-2021 - |
Question
I know this has been asked before here and I've viewed several similar questions, but I'm just not getting it and could use some assistance. I'm currently reading a file in SharePoint's library via an ajax query that is executed in clientContext.executeQueryAsync(), pretty much exactly as described in SharePoint's documentation:
$(document).ready(function(){
console.log("Javascript working");
$("#submit").click(function() {
file = readFile("/FileName.xlsx/Model/Tables('Table1')?$format=atom");
console.log(file);
});
});
function readFile(fileLocation) {
var clientContext;
var oWebsite;
var fileUrl;
clientContext = new SP.ClientContext.get_current();
oWebsite = clientContext.get_web();
clientContext.load(oWebsite);
clientContext.executeQueryAsync(function () {
fileUrl = "http://sharepoint2.bankofamerica.com/sites/HadoopAsAServicePortal/PlatformGovernance/_vti_bin/ExcelRest.aspx/Internal%20Team" + fileLocation;
$.ajax({
url: fileUrl,
type: "GET"
})
.done(Function.createDelegate(this, successHandler))
.fail(Function.createDelegate(this, errorHandler));
}, errorHandler);
}
function successHandler(data) {
// jsonData = xmlToJson(data.documentElement);
// cells = serialize(jsonData);
// pushCellsToLists(cells);
}
The problem is that, when I return the results of a successful query and print them, the result is undefined. I know this is because the query is being executed asynchronously while the console.log is not, and so the value isn't set when the console.log occurs. I also have heard that adding a callback is the solution here, but I'm not that familiar with callbacks and my attempts to implement that solution here have been unsuccessful. Can anyone offer any guidance?
Solution
I haven't used the _vti_bin/ExcelRest.aspx endpoint, so I'm not quite clear on all the aspects of your issue, but this is how I would structure it.
$(document).ready(function(){
$("#submit").click(function() {
console.log("this happens first");
var file = readFile("/FileName.xlsx/Model/Tables('Table1')?$format=atom")
.done(function(data){
console.log("this happens last");
console.log("File should be in this data somewhere.");
});
console.log(file);
console.log("^^^ that will be a jQuery deferred object because the actual contents aren't back yet.")
});
});
function readFile(fileLocation){
var fileUrl = site+"/_vti_bin/ExcelRest.aspx/Internal%20Team" + fileLocation;
return $.ajax({
url:fileUrl,
type:"GET"
// you may need headers
// you may need authorization
})
.then(function(data){
// you could preprocess or something with the data in here
console.log("this happens second");
// if you have actual data don't return it by itself
// obj, strings, boolean, etc. are "thenable" wrap with $.when()
return $.when(data);
})
.fail(function(data){
console.log("Error: REST failed");
console.log(data);
});
}
I don't see what your are doing with the SP execute query so I suggest you get rid of that.
Then the important thing with jQuery deferred is that at each point you return a thenable deferred object. Notice when I call $.ajax()
that I return that call. This allows the chain to continue.
And at each step in the .then() or .done() I return a thenable object.