1

I want to know what is the best way for using JS chaines promises in for SharePoint-Hosted Add-in.

In my code: I have a pageLoad function that's getting data from SP and I want to execute pageLoad first because I use its data in getUserData func.

Code:(App.js)

var clientContext = new SP.ClientContext.get_current();

// Executes when the HTML document is loaded and the DOM is ready
$(document).ready(onPageLoad()); // WHen i call this func in  $(function () 

$(function () {
    // when i call directly  onPageLoad() here, SHe is not implemented..
    var promise = onPageLoad();
    promise.then(function (currEmpLoginName) {
        return getUserData(currEmpLoginName);
    }).done(function (sender, args) {
      //getLastRecod(listname, userID);
    }).fail(function (sender, args) {
        // To do something 
    });
});


function onPageLoad() {
    var deferred = $.Deferred();
    var user = clientContext.get_web().get_currentUser();

    clientContext.load(user);
    clientContext.executeQueryAsync(Function.createDelegate(this, successHandler), Function.createDelegate(this, errorHandler));

    function successHandler() {
        var currEmpDispName = user.get_title();
        var badLoginName = user.get_loginName();
        currEmpLoginName = badLoginName.substring(badLoginName.lastIndexOf("|") + 1, badLoginName.lastIndexOf("@"));

        deferred.resolve(currEmpLoginName);
    }
    function errorHandler(sender, args) {
        var error = args[1].get_message();
        deferred.reject(error);
    }  
    return deferred.promise();
}

function getLastRecod(listname, userID){
var deferrend = $.deferrent

//async call

return deferred.promise();
}

Error is:

jQuery.Deferred exception: Unable to get property 'then' of undefined or null reference TypeError: Unable to get property 'then' of undefined or null reference at Anonymous function (https://lirexcom-9cf7bef551a412.sharepoint.com/sites/ioadd/AddHolidayReq/Scripts/App.js:12:5) at j (https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js:2:29941) at Anonymous function (https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js:2:30262) undefined jquery.min.js (2,31515) SCRIPT5007: Unable to get property 'then' of undefined or null reference jquery.min.js (2,31635)

My questions is:

  • I want to know if it is well structured code(Accept any estimation).
  • What is the best way to call 2nd function where i use her data for getUserData func.
  • Where i'm wrong? Thnx..
3

You have the right idea, and I went ahead and cleaned up the structure. In general, the goal of promises is to make asynchronous programming more like procedural programming. In general, you'll have a structure of

x().then(function(a) {
    return y(a);
}).then(function(b) {
    return z(b);
}) // ...

where data from asynchronous call x() feeds into async call y(), which feeds into async call z(). Think of it more as setting up dependencies between calls: z() depends on y() depends on x().

I replaced your first done() call with then(), which allows you to chain promises and avoid nesting any code. Essentially, the next part of chain responds to the second promise, not the first. Also, the second promise was created with data from the first promise, all without nesting code.

Your wrapper around the JSOM is just about correct. I modified it to pass the values through the resolve() call, since globals can make things a mess and don't seem necessary here.

var clientContext = new SP.ClientContext.get_current();
// I don't like globals
/*var currEmpID;
var currEmpDays;
var currEmpDispName;
var currEmpLoginName;*/

//$(document).ready(onPageLoad); // Redundant since $(...) is the same as $(document).ready(...)

$(function () {
    // When the function onPageLoad() has finished... 
    //$.when(onPageLoad()) // When() is not needed since we are only waiting on a single promise

    onPageLoad()
    // Use the info from the onPageLoad() promise, and send the promise from getUserData() on down the chain
    .then(function (currEmpDispName, badLoginName, currEmpLoginName) {
       return getUserData(currEmpLoginName);
    })
    // Use the info from the getUserData() promise
    .done(function (listname, userID) {
       getLastRecod(listname, userID);
    })
    .fail(function (sender, args) {
       // To do something 
    });
});

function onPageLoad() {
    var deferred = $.Deferred();
    var user = clientContext.get_web().get_currentUser();

    clientContext.load(user);

    function successHandler(d) {
        var currEmpDispName = user.get_title();
        var badLoginName = user.get_loginName();
        var currEmpLoginName = badLoginName.substring(badLoginName.lastIndexOf("|") + 1, badLoginName.lastIndexOf("@"));

        // Resolve the deferred with the desired user info
        deferred.resolve(currEmpDispName, badLoginName, currEmpLoginName);
    }
    function errorHandler(d) {
        welcomeText.innerHTML = "Request failed: " + arguments[1].get_message();
        deferred.reject(d);
    }  
    // Need to place after your function definitions
    clientContext.executeQueryAsync(Function.createDelegate(this, successHandler), Function.createDelegate(this, errorHandler));
    return deferred.promise();
}
  • This is error with your code below: jQuery.Deferred exception: Unable to get property 'then' of undefined or null reference TypeError: Unable to get property 'then' of undefined or null reference – Goshky Dec 30 '16 at 22:02

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.