0

I'm working on a SharePoint app where I need to run SP.RequestExecutor.executeAsync() in order to grab some information from one of the Host Web's lists. Depending on what method is calling the oData call I want to do something different.

Unfortuntely, executor.executeAsync() isn't playing as nice as $.ajax() does in terms of using $.when().done() and executing code after an async call is made. Below is some code if you'd like to see:

    load = function (){
        $.when(getEntries()).done(function () {
            ViewModels.Calendar.addEventSource(ko.utils.unwrapObservable(eventList));
        });
    }

    getEntries = function () {
        return executor.executeAsync({
            url: appweburl
                + "/_api/SP.AppContextSite(@target)/web/lists/getbytitle('" + LIST + "')/items?@target='" + hostweburl
                + "'&$select=Title,OData__x006e_ot5,qnlu,OData__x0066_x20"
                + "&$filter=OData__x0066_x20 eq '" + ViewModels.Person.user.userName() + "' "
                + "and qnlu ge DateTime'" + startDate().toString("yyyy-MM-dd") + "T00:00:00' "
                + "and qnlu le DateTime'" + endDate().toString("yyyy-MM-dd") + "T00:00:00' ",
            method: "GET",
            headers: { "Accept": "application/json; odata=verbose" },
            success: onGetEntriesSuccess,
            error: onoDataCallFailure 
        });
    },

    onGetEntriesSuccess = function (data) {
        var jsonObject = JSON.parse(data.body);
        $.each(jsonObject.d.results, function (index, item) {
            eventList.push(new Event(item.qnlu, item.OData__x006e_ot5));
        });
    },

    onoDataCallFailure = function (data, errorCode, errorMessage) {
        alert('Failed to get host site. Error:' + errorMessage);
    };

Any ideas/suggestions would be appreciated.

2

Create a new .Deferred. Return Deferred.promise from the call. Call Deferred.resolve or Deferred.Reject in the succs and failure handlers.

8

To add some detail to Scot's answer, you could do something like this:

function load () {
    var call = getEntries();
    call.done(function (eventList) {
        ViewModels.Calendar.addEventSource(ko.utils.unwrapObservable(eventList));
    });
}

function getEntries () {
    // create the deferred object
    var def = new $.Deferred();

    executor.executeAsync({
        url: appweburl
            + "/_api/SP.AppContextSite(@target)/web/lists/getbytitle('" + LIST + "')/items?@target='" + hostweburl
            + "'&$select=Title,OData__x006e_ot5,qnlu,OData__x0066_x20"
            + "&$filter=OData__x0066_x20 eq '" + ViewModels.Person.user.userName() + "' "
            + "and qnlu ge DateTime'" + startDate().toString("yyyy-MM-dd") + "T00:00:00' "
            + "and qnlu le DateTime'" + endDate().toString("yyyy-MM-dd") + "T00:00:00' ",
        method: "GET",
        headers: { "Accept": "application/json; odata=verbose" },
        success: onGetEntriesSuccess,
        error: onoDataCallFailure 
    });

    function onGetEntriesSuccess (data) {
        var jsonObject = JSON.parse(data.body);
        var eventList = [];
        $.each(jsonObject.d.results, function (index, item) {
            eventList.push(new Event(item.qnlu, item.OData__x006e_ot5));
        });

        // resolve the deferred object
        // eventList will be passed as parameter to done
        def.resolve(eventList);
    }

    function onoDataCallFailure (data, errorCode, errorMessage) {
        // reject the deferred object            
        def.reject('Failed to get host site. Error:' + errorMessage);
    }

    // return the promise
    return def.promise();
}
  • Thanks, this was really helpful. I'll keep it around for further reference. In the meantime I was able to work around it and it's been a while since I looked at the code so I think I'll keep it stable for now but again, this will be extremely useful going forward. – EHorodyski Aug 20 '13 at 12:41
  • Sorry, I edited again because the suggested edit was wrong. return def.promise(); is the right way to return promises. With the previous edit, what was returned is the original Deferred object, not the promise. It's a slight difference, but it's different (a promise hides the underlying Deferred state, then thus cannot be changed). – MdMazzotti Mar 25 '14 at 11:31
  • You can use both, but as you say, there was not real wrong in the original post. Let's revert this to it's original state – Robert Lindgren Mar 25 '14 at 11:38
  • I have to make multiple ajax calls, how can I loop them with the SP.RequestExecutor? – Sandrooco Oct 12 '16 at 13:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.