Display All Tasks in Site Collection

Sep 13, 2014 at 12:19 AM
Edited Sep 13, 2014 at 12:20 AM
Hi all,

I am using the awesome spservices to iterate through all the task lists in a site collection. I have the code working, but it seems a big sluggish. Do you have any recommendations on how I might make it more performant?
<script src="https://mysubdomain.sharepoint.com/HomePageAssets/jquery-1.10.2.min.js"></script>
<script src="https://mysubdomain.sharepoint.com/HomePageAssets/jquery.SPServices-2014.01.min.js"></script>

<div id="myStatusMessage">Loading task lists...</div>
<div id="myProjectList"></div>

<script>
function myContentType(myListName, myList_ItemCount, myList_ItemURL){           
    $().SPServices({
        operation:"GetListContentTypes",
        listName: myListName,
        async:false,
        completefunc: function(xData, Status) {
            $(xData.responseXML).SPFilterNode("ContentType").each(function() {
                myContentTypeName = $(this).attr("Name");   
                // Task List? Only proceed to the next function if it is.
                if (myContentTypeName === "Task"){
                    myGetFullTaskList(myListName, myList_ItemCount, myList_ItemURL)
                }              
            })
        }
    })      
}

function myGetFullTaskList(myListName, myList_ItemCount, myList_ItemURL){

    var myCurrentListCompletedItems = 0;
    var myList_ItemURL_Hyperlink = "<a href='https://mysubdomain.sharepoint.com" + myList_ItemURL + "'>https://mysubdomain.sharepoint.com" + myList_ItemURL + "</a>";

    $().SPServices({
        operation: "GetListItems",
        listName: myListName, // "Tasks",
        CAMLViewFields: "<ViewFields><FieldRef Name='Status'/></ViewFields>",
        CAMLQuery: "<Query><Where><Eq><FieldRef Name='Status' /><Value Type='Choice'>Completed</Value></Eq></Where></Query>",
        CAMLRowLimit: 0,
        async:false,
        completefunc: function(xData, Status) {
            $(xData.responseXML).SPFilterNode("z:row").each(function() {
                // Count number of completed items for this list.
                myCurrentListCompletedItems = myCurrentListCompletedItems + 1;
                var TaskItemTitle = $(this).attr("ows_Title")   
                var TaskItemStatus = $(this).attr("ows_Status")
                var TaskItemLink =  $(this).attr("ows_FileRef") 
            })
        }
    })  
    // Output List General Data
    var myList_ItemCountNumeric = parseInt(myList_ItemCount);
    // If the number of completed items do not match the total, then show the info
    if (myList_ItemCountNumeric != myCurrentListCompletedItems) {
        var myAppendString = "<p><strong>" + myListName + "</strong> (" + myList_ItemCount + " items)<br>";
        $("#myProjectList").append(myAppendString); 
        var myThisListInfo = "Tasks Completed: " + myCurrentListCompletedItems + "/" + myList_ItemCount + "<br>" + myList_ItemURL_Hyperlink + "</p><hr>";
        $("#myProjectList").append(myThisListInfo);
    }
}


function myGetAllTheLists() {
    $().SPServices({
               operation:"GetListCollection",
               async:false,
               completefunc: function(xData, Status) {
                   $(xData.responseXML).SPFilterNode("List").each(function() {
                       myListName = $(this).attr("Title");
                        myList_ListDescription = $(this).attr("Description")
                        myList_ItemCount = $(this).attr("ItemCount");
                        myList_ItemURL = $(this).attr("DefaultViewUrl");
                       myContentType(myListName, myList_ItemCount, myList_ItemURL)
                   })
               }
    })
}

function myHideStatus() {
    $( "#myStatusMessage" ).hide();
}

$(document).ready(function() {
    myGetAllTheLists()
    myHideStatus();
}); // End document ready

</script>
Thank you for the advice!
Carl
Coordinator
Sep 13, 2014 at 4:30 AM
Carl:

The first thing I would recommend is to switch to using promises rather than synchronous calls. That will stop the browser blocking. The other thing to look at is how you can reduce the number of calls.

M.
Marked as answer by mrentropy on 9/26/2014 at 9:56 AM
Sep 16, 2014 at 11:14 PM
Edited Sep 16, 2014 at 11:15 PM
Thank you very much, Marc! I will start educating myself about promises. If you have time for a related question I was noticing that GetListCollection returns an awful lot of metadata. I was reading that if you want to return only those fields you need you can add the query options below, but they don't seem to be impacting anything for me. Do you see any n00b mistakes?
.
.
CAMLViewFields: "<ViewFields><FieldRef Name='Title' /><FieldRef Name='Description' /><FieldRef Name='ItemCount' /><FieldRef Name='DefaultViewUrl' /></ViewFields>",
CAMLQuery: "<QueryOptions><IncludeMandatoryColumns>FALSE</IncludeMandatoryColumns><ViewFieldsOnly>TRUE</ViewFieldsOnly></QueryOptions>",
CAMLRowLimit: 0,
.
.
Best regards,
Carl
Sep 16, 2014 at 11:53 PM
Ah, nevermind...I see you have already discussed this issue. Once again thanks for all the documentation/discussions here, though. Certainly helps!
https://spservices.codeplex.com/discussions/248939
Sep 26, 2014 at 5:56 PM
Edited Sep 26, 2014 at 5:57 PM
Hi Marc,

I thought I would just mention for future users reading this post that your suggestion above worked perfectly! It's much faster with promises and less calls. I was also highly inspired by the example you gave in this other post -- I didn't know about the "ServerTemplate" attribute and I was able to avoid using GetListContentTypes.

http://spservices.codeplex.com/discussions/568301

Thanks again, for the help!
Carl
Coordinator
Sep 28, 2014 at 9:55 AM
You're welcome, Carl.

M.