Question

I keep getting undefined error in this function. It's broken down into 5 individual functions and I'm trying to have each run after the previous one is complete but using the data returned from the previous function. I could nest all the callbacks but I'd rather use promises.

var checkedOutReport = function () { 
    var rootSite = window.location.protocol + "//" + window.location.hostname;

    //Create array with each collection site
    function getAllSites (){
        var d = $q.defer();
        var allSites = [];

        $().SPServices({
            operation: "GetAllSubWebCollection",
            completefunc: function (xData,Status){
                var result = $(xData.responseXML);

                result.find('Web').each(function (){
                    var self = $(this);
                    allSites.push({
                        siteTitle: self.attr('Title'),
                        siteUrl: self.attr('Url')   
                    })
                })  
            }
        })
        d.resolve(allSites)
        return d.promise;
    }
    //Get libraries for each siteUrl
    function getSiteLibraries (allSites) {
        var siteCount = allSites.length;
        var listPromise = [];

        //Go through each site and find document libraries 
        for (var i = 0; i < siteCount; i++){
            listPromise[i] = $().SPServices({
                operation: "GetListCollection",
                webURL: allSites[i].siteUrl
            })
        }

        //Promise array contains all lists for each site
        //Get libraries for each site 
        $q.all(listPromise).then(findLibraries(listPromise))
    }
    function findLibraries (promises){
        var d = $q.defer();
        var siteCount = promises.length;
        var allLibraries = [];
        //For each site, find the document libraries
        for (var i = 0; i < siteCount; i++){
            $(promises[i].responseXML).find("List[ServerTemplate='101']").each(function(){
                var self = $(this);
                allLibraries.push({
                    listName = self.attr('Title'),
                    listId = self.attr('ID'),
                    siteUrl = allSites[i].siteUrl
                })
            })
        }
        console.log(allLibraries);
        d.resolve(allLibraries);
        return d.promise;
    }

    //CAML QUERIES
    var cQueryOptions = "<QueryOptions><ViewAttributes Scope='RecursiveAll' IncludeRootFolder='True' /></QueryOptions>",
        cQueryAllCheckedOutDocuments = '<Query><Where><IsNotNull><FieldRef Name="CheckoutUser" /></IsNotNull></Where></Query>',
        cQueryModifiedBySystemAccount = '<Query><Where><Contains><FieldRef Name="Editor" /><Value Type="User">system</Value></Contains></Where></Query>',
        cViewFields = "<ViewFields Properties='True' />";

    //For each library in site collection, find documents which meet criteria 
    function searchLibraries (library) {
        var libraryCount = library.length;
        var itemPromise = [];

        for (var i = 0; i < libraryCount; i++){
            itemPromise[i] = $().SPServices({
                operation: "GetListItems",
                webURL: library[i].siteUrl,
                listName: library[i].listID,
                CAMLViewFields: cViewFields,
                CAMLQuery: cQueryAllCheckedOutDocuments
            })
        }

        $q.all(itemPromise).then(parseSearchResult(itemPromise))
    }
    //Clean up result
    function parseSearchResult(result){
        var d = $q.defer()
        var resultCount = result.length; 
        var returnedFiles = [];
        for(var i = 0; i < resultCount; i++){
            $(result[i].responseXML).SPFilterNode("z:row").each(function (){
                var self = $(this);

                var fileName = self.attr('ows_LinkFilename');
                var fileUrl = self.attr('ows_FileDirRef').split("#");
                var checkedTo = self.attr('ows_LinkCheckedOutTitle');
                var modified = self.attr('ows_Modified');

                returnedFiles.push({
                    fileName: fileName,
                    fileUrl: fileUrl[1],
                    checkedTo: checkedTo,
                    modified: modified
                });
            })
        }
        d.resolve(returnedFiles);
        return d.promise;
    }

    getAllSites()
        .then(
            getSiteLibraries(allSites)
            )
        .then(
            searchLibraries(allLibraries)
            );
}
Était-ce utile?

La solution

There are quite a few problems here. I will try my best to describe as many as I can find. There are likely several more...

d.resolve(allSites) needs to be inside the completefunc callback as you don't want to resolve the promise until allSites is populated.

getSiteLibraries() and searchLibraries() need to return their promises.

findLibraries() and parseSearchResult() don't have any async code so there's no need to return promises, just return the results.

$q.all(listPromise).then(findLibraries(listPromise)) actually executes findLibraries() immediately, simply use $q.all(listPromise).then(findLibraries). Same goes for $q.all(itemPromise).then(parseSearchResult(itemPromise)).

Same goes for...

getAllSites()
    .then(
        getSiteLibraries(allSites)
        )
    .then(
        searchLibraries(allLibraries)
        );

Change to:

getAllSites()
    .then(
        getSiteLibraries
        )
    .then(
        searchLibraries
        );

With the above changes applied...

var checkedOutReport = function () { 
    var rootSite = window.location.protocol + "//" + window.location.hostname;

    //Create array with each collection site
    function getAllSites (){
        var d = $q.defer();
        var allSites = [];

        $().SPServices({
            operation: "GetAllSubWebCollection",
            completefunc: function (xData,Status){
                var result = $(xData.responseXML);

                result.find('Web').each(function (){
                    var self = $(this);
                    allSites.push({
                        siteTitle: self.attr('Title'),
                        siteUrl: self.attr('Url')  
                    })
                })  
                d.resolve(allSites); // resolve only when complete
            }
        });
        return d.promise;
    }
    //Get libraries for each siteUrl
    function getSiteLibraries (allSites) {
        var siteCount = allSites.length;
        var listPromise = [];

        //Go through each site and find document libraries 
        for (var i = 0; i < siteCount; i++){
            listPromise[i] = $().SPServices({
                operation: "GetListCollection",
                webURL: allSites[i].siteUrl
            })
        }

        //Promise array contains all lists for each site
        //Get libraries for each site 
        return $q.all(listPromise).then(findLibraries); // need to return the promise
    }
    function findLibraries (promises){
        var siteCount = promises.length;
        var allLibraries = [];
        //For each site, find the document libraries
        for (var i = 0; i < siteCount; i++){
            $(promises[i].responseXML).find("List[ServerTemplate='101']").each(function(){
                var self = $(this);
                allLibraries.push({
                    listName: self.attr('Title'),
                    listId: self.attr('ID'),
                    siteUrl: allSites[i].siteUrl
                })
            })
        }
        console.log(allLibraries);
        return allLibraries; // don't need a promise here
    }

    //CAML QUERIES
    var cQueryOptions = "<QueryOptions><ViewAttributes Scope='RecursiveAll' IncludeRootFolder='True' /></QueryOptions>",
        cQueryAllCheckedOutDocuments = '<Query><Where><IsNotNull><FieldRef Name="CheckoutUser" /></IsNotNull></Where></Query>',
        cQueryModifiedBySystemAccount = '<Query><Where><Contains><FieldRef Name="Editor" /><Value Type="User">system</Value></Contains></Where></Query>',
        cViewFields = "<ViewFields Properties='True' />";

    //For each library in site collection, find documents which meet criteria 
    function searchLibraries (library) {
        var libraryCount = library.length;
        var itemPromise = [];

        for (var i = 0; i < libraryCount; i++){
            itemPromise[i] = $().SPServices({
                operation: "GetListItems",
                webURL: library[i].siteUrl,
                listName: library[i].listID,
                CAMLViewFields: cViewFields,
                CAMLQuery: cQueryAllCheckedOutDocuments
            })
        }

        return $q.all(itemPromise).then(parseSearchResult); // need to return promise
    }
    //Clean up result
    function parseSearchResult(result){
        var resultCount = result.length; 
        var returnedFiles = [];
        for(var i = 0; i < resultCount; i++){
            $(result[i].responseXML).SPFilterNode("z:row").each(function (){
                var self = $(this);

                var fileName = self.attr('ows_LinkFilename');
                var fileUrl = self.attr('ows_FileDirRef').split("#");
                var checkedTo = self.attr('ows_LinkCheckedOutTitle');
                var modified = self.attr('ows_Modified');

                returnedFiles.push({
                    fileName: fileName,
                    fileUrl: fileUrl[1],
                    checkedTo: checkedTo,
                    modified: modified
                });
            })
        }
        return returnedFiles; // don't need a promise here
    }

    getAllSites()
        .then(
            getSiteLibraries
            )
        .then(
            searchLibraries
            );
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top