Tallan's Technology Blog

Tallan's Top Technologists Share Their Thoughts on Today's Technology Challenges

Use SP.SOD.executeFunc(a,b,c) to load the SharePoint JavaScript libraries when needed

Patrick Kelly

A couple weeks ago, I was building a stock quote for a master page that required two images stored in /Style Library/Custom/; the images represented the typical stock quote arrows. In order to provide the JavaScript code with the correct location of the site collection’s root I was using the following directly in my code block:

var imgArrow = <asp:Literal runat=”server” Text=”<%$SPUrl:~sitecollection/

    Style Library/Custom/images/stockup.png%>” />;

While I had originally thought this was a kludgey solution to begin with, it was getting the job done every single time.

However, a problem arose a few days after when I began refactoring the code. I had moved all of the js code from the master page itself into a separate js file, leaving only a static reference to the script on the master. The following code should be put within the ScriptManager control.

<asp:ScriptReference Path="<%$SPUrl:~sitecollection/Style Library/

    Custom/scripts/custom.js%>" />

Since the code was moved off the aspx page, I quickly lost the ability to use the $SPUrl server-side variable. So instead I decided to grab the site collection root url via SP’s JSOM.

var siteUrl;

var ctx = new SP.ClientContext();


var site = ctx.get_site();

ctx.load(site);

ctx.executeQueryAsync(

    Function.createDelegate(this, OnSuccess),

    Function.createDelegage(this, OnFail));


function OnSuccess() {

    siteUrl = site.get_url();

}

function OnFail() {

    //fail gracefully

}

The code is semi-incomplete in that there were more operations running in the OnSuccess callback, but you can glean that the siteUrl variable will be used in other functions in the file.

When I put this code into action, I immediately received SP.ClientContext undefined errors, which weren’t making sense to me as I can see that the browser had loaded the file. I was even able to go to the developer console and execute functions in the SP.js file by hand. After scouring the web for information it appeared the SP.js file, with many others, were registered as Script On Demand scripts via SharePoint.

A quick analysis of the rendered markup versus the master page itself shows that the ContentPlaceHolder, “PlaceHolderUtilityContent,” is in charge of registering a set of OOTB JavaScript libraries. This placeholder is found at the very bottom of the v4.master, outside of the <form> tag. Note the function being called, RegisterSOD.

zd24gix0.35h5

SharePoint’s JavaScript class library, which can be found here, is almost entirely loaded in an on demand fashion to keep the client-rendering times down. To execute a function contained anywhere in the library, such as SP.ClientContext, the script must be readied before your custom code is executed.

Since the documentation around the SP.SOD namespace (SharePoint Scripts On Demand) is semi-lacking, it appears the developer community is a little undecided on the best way to load, or make ready, a script that was registered as an on demand script by SharePoint. I will quickly demonstrate an easy way to “ready” an OnDemand script.

var site;

var siteUrl;


function initCustom() {

    // independent calls here    


    // dependent calls here

    SP.SOD.executeFunc('sp.js', 'SP.ClientContext', function () {

        var ctx = new SP.ClientContext();

        site = ctx.get_site();


        ctx.load(site);

        ctx.executeQueryAsync(Function.createDelegate(this, OnSuccess),

                Function.createDelegate(this, OnFail));

    });

}


function OnSuccess() {

    loadContent();

}


function OnFail() {

    //fail gracefully

}

To get things moving, I kick off the initCustom function via jQuery.

$(Document).ready(initCustom);

Then I run the SP.SOD.executeFunc(a,b,c) function to ready the SP.js file. It’s primary purpose it to ready the file that the SP.ClientContext function (specified in parameter b), is found in. The first parameter is the key that the script was registered under during the RegisterSOD call earlier. The last parameter is the callback function to execute when the script has finished loading.

It’s not apparent to me why this isn’t discussed more across the web and why so many developers are doing this differently in every case. Now that I’ve more knowledge of the SOD namespace, it make utter sense as to what they’re trying to accomplish. I hope this helps!

1 Comment. Leave new

Man, you are a life saver.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

\\\