I have found allot of resources which point out how to handle a simple promise or deferred Async call in SharePoint apps. (for example) But I cant understand how to properly use a promise if I am performing some work on the returned data before I want the promise resolved.

below I have a restHelper.js Module which contains the ajax call and then I have the App.js calling the restHelper function, how can I defer the drawUserData() function until the objectCache has been populated by the _onRestPeopleSearchSucceeded function?



var restHelper = (function () {
var objectCache = {};

var peopleSearchQuery = function (options) {

var getQueryStringParameter = function (urlParameterKey) {
    return _getQueryStringParameter(urlParameterKey);

var _restPeopleSearchQuery = function (options) {
    var searchUrl = "/_api/search/query?querytext='" + options.queryProperty + ":" + options.queryValue + "'&sourceid='b09a7990-05ea-4af9-81ef-edfab16c4e31'";
    var appWebUrl = getQueryStringParameter("SPAppWebUrl");
    var fullUrl = appWebUrl + searchUrl;
            url: fullUrl,
            type: "GET",
            headers: {
                "accept": "application/json; odata=verbose",
                "content-type": "application/json; odata=verbose"
            success: _onRestPeopleSearchSucceeded,
            error: _onRestPeopleSearchFailed

var _onRestPeopleSearchSucceeded = function (data) {
    // fill cache object with people objects
    var data = data.d.query.PrimaryQueryResult.RelevantResults.Table.Rows.results
    for (var i = 0; i < data.length; i++) {
        var results = data[i].Cells.results;
        // Create an object for each person and store it in the global store
        var person = {};
        // Loop through all returned data and create key value pair object for each
        // TODO, check if array or object, map will not work for objects of objects
        results.map(function (p) {
            var newPropertyName = p.Key
            // ChangeCase js Package to change the capitalisation on the first letter (the Key in this data is capitalised) 
            person[newPropertyName] = p.Value
        // Create SearchPeopleCache object in the ObjectCache if it doesnt already exist and store the person Object
        if (!(objectCache.hasOwnProperty('searchPeopleResults'))) {
            objectCache['searchPeopleResults'] = {};
        if (!(objectCache.searchPeopleResults[person.UserProfile_GUID])) {
            objectCache.searchPeopleResults[person.UserProfile_GUID] = person;

var _onRestPeopleSearchFailed = function (err) {
    // return error to Console or log error to App

// Allows pulling variables from query string paramters
var _getQueryStringParameter = function (urlParameterKey) {
    var params = document.URL.split('?')[1].split('&');
    var strParams = '';
    for (var i = 0; i < params.length; i = i + 1) {
        var singleParam = params[i].split('=');
        if (singleParam[0] == urlParameterKey)
            return decodeURIComponent(singleParam[1]);

return {
    objectCache: objectCache,
    peopleSearchQuery: peopleSearchQuery,
    getQueryStringParameter: getQueryStringParameter,



$(document).ready(function () {
    // Prepare Global Window variables
    window.departmentProperty = "ICT Infrastructure - Sharepoint"; // decodeURIComponent(getQueryStringParameter("Department"));
    window.hostUrl = decodeURIComponent(restHelper.getQueryStringParameter("SPHostUrl"));
    window.appWebUrl = restHelper.getQueryStringParameter("SPAppWebUrl");
    window.scriptbase = hostUrl + "/_layouts/15/";
    window.profilesSearchArray = {};
    // set window department name
    // Get initial data from search and set window
    var options = {
        queryProperty: "Department",
        queryValue: departmentProperty

    // Create new Promise for Async Call
    // below relies on above completing
  • Note that SP has at least 3 different ways of getting QueryString parameters, so you do not need the getQueryStringParameter used in many examples. ► sharepoint.stackexchange.com/questions/159289/… May 9, 2016 at 15:31
  • Fyi you don't have to use jQuery deferred etc when you have native promise support in JS. Just find a polyfill if you want to support browsers less than IE 10
    – Akhoy
    May 9, 2016 at 18:48

1 Answer 1


As your restHelper.peopleSearchQuery(options);is a promise, you can call that function and add a then() which in turn calls drawUserData

  • using .then( ) is the correct answer, Note that OPs code does not return Promises in the main function (his main function is an IIFE which returns an object), so he has to fix that to make Promise chaining work May 10, 2016 at 7:45
  • 1
    Danny, when use .then() I get Uncaught TypeError: Cannot read property 'then' of undefined What do I need to do to make it return a Promise? can you point me in the right direction May 10, 2016 at 13:34
  • 1
    @Col.Cook it should be enough to just add return jQuery.ajax(.. in your _restPeopleSearchQuery function, and return _restPeopleSearchQuery(options); in your peopleSearchQuery function. May 11, 2016 at 8:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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