Take the 2-minute tour ×
SharePoint Stack Exchange is a question and answer site for SharePoint enthusiasts. It's 100% free, no registration required.

If you look at below code, I have used executeordelayuntillscriptloaded at start of my script so that it will run only after that file is loaded. But this breaks some functionality. Can you check this code and tell me if its not good practice?

It was done so that the SP.Utilities.Utility.getLayoutsPageUrl functionality never throw undefined error:

 <SharePoint:ScriptLink ID="ScriptLink1" name="SP.js" runat="server"
    ondemand="false" localizable="false" loadafterui="true" />
<SharePoint:ScriptLink ID="ScriptLink2" name="SP.UserProfiles.js" runat="server"
    ondemand="false" localizable="false" loadafterui="true" />

<script type="text/javascript">
SP.SOD.executeOrDelayUntilScriptLoaded(runthiscode, 'SP.js');

function runthiscode()
{
    var personProperties;

    // Ensure that the SP.UserProfiles.js file is loaded before the custom code runs.    

    SP.SOD.executeOrDelayUntilScriptLoaded(getUserProperties, 'SP.UserProfiles.js');

    function getUserProperties() {  

        // Get the current client context and PeopleManager instance.
        var clientContext = new SP.ClientContext.get_current();
        var peopleManager = new SP.UserProfiles.PeopleManager(clientContext);

        // Get user properties for the target user.
        // To get the PersonProperties object for the current user, use the
        // getMyProperties method.
        personProperties = peopleManager.getMyProperties();

        // Load the PersonProperties object and send the request.
        clientContext.load(personProperties);
        clientContext.executeQueryAsync(onRequestSuccess, onRequestFail);
    }

    // This function runs if the executeQueryAsync call succeeds.
    function onRequestSuccess() {       

        if (personProperties.get_userProfileProperties().CustomPropertyValue == "False") {

          window.location(SP.Utilities.Utility.getLayoutsPageUrl('')+'someurl.aspx');

        }

    }

    // This function runs if the executeQueryAsync call fails.
    function onRequestFail(sender, args) {
        var r = confirm("There was an error, the page will reload");

              window.location(SP.Utilities.Utility.getLayoutsPageUrl('')+'someurl.aspx'); 
    }

 function someotherfunction() {

        window.location.href = SP.Utilities.Utility.getLayoutsPageUrl('')+'someotherurl';

    }
}
</script>
share|improve this question
    
if your code depends on some other js file, I would call it a must more than a best practice. This is the documented way in SharePoint to wait for a script (with ondemand="false") to be fully loaded before executing some custom code that depends on it. –  MdMazzotti Apr 4 at 10:48
    
Is my above code best practice? what happens turning ondeamnd=on (just asking). –  variable Apr 4 at 10:49
    
I would recommend that you read this post here on SP.SE: sharepoint.stackexchange.com/a/58509/8642 –  MdMazzotti Apr 4 at 10:53
    
Use SP.SOD.executefunc('sp.js','SP.ClientContext',runthiscode); –  Unnie Apr 4 at 11:23

2 Answers 2

up vote 2 down vote accepted

Use SP.SOD.executeFunc('sp.js','SP.ClientContext',runthiscode); instead of SP.SOD.executeOrDelayUntilScriptLoaded. because SP.SOD.executefunc makes sure the file is loaded and then executes the method and SP.SOD.executeOrDelayUntilScriptLoaded will only put the method on queue untill the file is loaded(so if file is not loaded then never executes). SP.SOD.executeFunc loads on demand scripts, so script link should be added for that js file.

<SharePoint:ScriptLink ID="ScriptLink2" name="SP.UserProfiles.js" runat="server"
    ondemand="false" localizable="false" loadafterui="true" />
     <script type="text/javascript">
        SP.SOD.executeFunc('sp.js','SP.ClientContext',runthiscode);
        function runthiscode()
        {

                // Ensure that the SP.UserProfiles.js file is loaded before the custom code runs.    
                SP.SOD.executeFunc('SP.UserProfiles.js','SP.UserProfiles',getUserProperties);
       }
        var personProperties;
            function getUserProperties() {  

                // Get the current client context and PeopleManager instance.
                var clientContext = new SP.ClientContext.get_current();
                var peopleManager = new SP.UserProfiles.PeopleManager(clientContext);

                // Get user properties for the target user.
                // To get the PersonProperties object for the current user, use the
                // getMyProperties method.
                personProperties = peopleManager.getMyProperties();

                // Load the PersonProperties object and send the request.
                clientContext.load(personProperties);
                clientContext.executeQueryAsync(onRequestSuccess, onRequestFail);
            }

            // This function runs if the executeQueryAsync call succeeds.
            function onRequestSuccess() {       

                if (personProperties.get_userProfileProperties().CustomPropertyValue == "False") {

                  window.location(SP.Utilities.Utility.getLayoutsPageUrl('someurl.aspx');

                }

            }

            // This function runs if the executeQueryAsync call fails.
            function onRequestFail(sender, args) {
                var r = confirm("There was an error, the page will reload");

                      window.location(SP.Utilities.Utility.getLayoutsPageUrl('someurl.aspx'); 
            }



        </script>
share|improve this answer
    
sorry but how can it make sure that it is loaded if we are not specifiying it in head tag to load it? is it true? –  variable Apr 4 at 11:41
1  
SP.js is loaded by sharepoint by default. SP.SOD.executefunc('SP.UserProfiles.js','SP.UserProfiles',getUserProperties); will explicitly load this file if already not loaded. So you don't have to load it by using script link in head. –  Unnie Apr 4 at 11:55
    
Ok, cool, is the logic same if this code would go on a masterpage instead of an application page? –  variable Apr 5 at 5:00
    
Also, the last function 'someotherfunction' (its a href javascript on an <a href= tag) uses SP.Utilities.Utility.getLayoutsPageUrl, so dont you think this as well needs to go under execute func? –  variable Apr 5 at 5:04
    
If I use your technique then the code wont run, I tested by putting an alert box, under runthiscode(), it doesnt show up.! –  variable Apr 5 at 7:59

Prefer SP.SOD.executeFunc over SP.SOD.executeOrDelayUntilScriptLoaded

Since SP.SOD.executeFunc supports load on demand scripts, there is no need to reference explicitly SP JavaScript files using SharePoint:ScriptLink

The following example demonstrates how to initialize UserProfiles CSOM in application page:

SP.SOD.executeFunc('SP.js', 'SP.ClientContext', function() {
   // Make sure PeopleManager is available 
   SP.SOD.executeFunc('userprofile', 'SP.UserProfiles.PeopleManager', function() {

      var clientContext = new SP.ClientContext.get_current();
      var peopleManager = new SP.UserProfiles.PeopleManager(clientContext);

      //...

   });

});

Usage of SP.Utilities.Utility.getLayoutsPageUrl

SP.Utilities.Utility.getLayoutsPageUrl(pageName) Method accepts pageName as a parameter.

Example: how to get Settings page url

var pageUrl = SP.Utilities.Utility.getLayoutsPageUrl("Settings.aspx");
share|improve this answer
    
SP.Utilities.Utility.getLayoutsPageUrl needs to be under SP.SOD.executeFunc('SP.js', 'SP.ClientContext', function() { ? –  variable Apr 4 at 11:39
    
that's correct since SP.Utilities.Utility.getLayoutsPageUrl is a part of SP.js –  Vadim Gremyachev Apr 4 at 11:46
    
Now I will place the entire js code under SP.SOD.executeFunc('SP.js', 'SP.ClientContext', function() { // Make sure PeopleManager is available SP.SOD.executeFunc('userprofile', 'SP.UserProfiles.PeopleManager', function() { –  variable Apr 4 at 12:05
    
@VadimGremyachev "no need to reference explicitly SP JavaScript files using SharePoint:ScriptLink": if in a custom page I know beforehand that I'm going to need some js file, then I think it perfectly makes sense to explicitly load it via ScriptLink. In the end, that's why they provided two different functions: they serve different needs –  MdMazzotti Apr 5 at 9:24
    
@MdMazzotti I agree with you –  Vadim Gremyachev Apr 5 at 10:58

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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