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?

Was it helpful?

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with sharepoint.stackexchange
scroll top