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

I am iterating through subsites\subwebs to see if a particular list exists in every subsite. The issue I am facing is that, if a list does not exist in one subsite the whole script stops from processing further with error:- Request failed. List 'Documents' does not exist at site with URL 'https://sharepoint.com/teams/MySite/Myweb'

What I was trying is to get away with this error and script should continue looking at next subsite. So I used Try catch, thinking that it would continue processing. But no luck. And seems like there is no direct way to check in JSOM equivalent to "tryGetList"in server obj model. Any ideas how to get away with this issue in JSOM?

Below is my script Snippet that halts as soon as it doesn't find a list in a subsite.

context.executeQueryAsync(
          Function.createDelegate(this, function (sender, args) {
                 listItemsCollection = [];
              for (var x = 0; x < webSubSites.get_count(); x++) {
                  var subWeb = webSubSites.itemAt(x); 
                  try{                          
                      var spListobj = subWeb.get_lists().getByTitle('Documents');
                  }
                  catch (err){  //Script breaks at this line for a subsite that dosent has Documents library.
                      alert(subWeb.get_title());
                      return false;
                  }
                      var camlQuery = new SP.CamlQuery();
                      camlQuery.set_viewXml('<View><Query></Query></View>');
                      var spListobjItems = spListobj.getItems(camlQuery);

                      var itemDetails = new Object;
                      itemDetails.ListItems = spListobjItems;
                      listItemsCollection.push(itemDetails);
                      context.load(spListobjItems, 'Include(File)');  


                }//end for

Thanks,

share|improve this question
    
Why do you make a return of "false" on error? That will escape the whole method –  Robert Lindgren Jun 13 at 16:55
    
I removed "return false" and tested the issue still exists. –  user117048 Jun 13 at 17:49

3 Answers 3

up vote 3 down vote accepted

I believe your code has one fundamental flaw. Since JSOM is an async API, you cant perform this kind of checking since list objects have to be requested first and only then in the success handler of SP.ClientContext.executeQueryAsync method to perform checking.

I strongly encourage you to read an article Asynchronous programming in apps for Office to get acquainted with asynchronous programming concepts and patterns.


CSOM/JSOM API does not contains "built-in" method to determine whether list exists or not, but you could use the following approach.

The solution is to load Web object with lists collection and then iterate through list collection to find a specific list:

context.load(subWebs, 'Include(Title,Lists)');

The following example demonstrates how to iterate web sites and find specific list:

function findLists(listTitle)
{
   var context = SP.ClientContext.get_current();
   var web = context.get_web(); 
   var site = context.get_site();
   var rootWeb = site.get_rootWeb();
   var subWebs = rootWeb.get_webs();

   context.load(subWebs, 'Include(Title,Lists)');
   context.executeQueryAsync(
    function () {  
         for (var i = 0; i < subWebs.get_count(); i++) {
            var subWeb = subWebs.itemAt(i);
            var lists = subWeb.get_lists();
            if(get_listExists(lists,listTitle)) { //Lists property is initialized 
               console.log(subWeb.get_title());
            }
         }
    },
    function (sender, args) {
       console.log(args.get_message());
    }
   );   
}



function get_listExists(lists,listTitle)
{
    var listExists = false;
    var le = lists.getEnumerator();
    while (le.moveNext()) {
         var list = le.get_current();
            if(list.get_title() == listTitle) {
              listExists = true;
              break;
         }
    }
    return listExists;
}



//Usage
findLists('Documents');
share|improve this answer
1  
Clever, didn't think of that :) –  Anders Aune Jun 13 at 17:56
    
Thanks very much!! That really helped. I will go through the asynch programming concepts. –  user117048 Jun 13 at 18:14

I think maybe the right way is to use the SP.ExceptionHandlingScope

Here is a simple example:

    function checkIfDocumentLibExists() {

       var context = SP.ClientContext.get_current();
       var web = context.get_web();

        try {

           var scope = new SP.ExceptionHandlingScope(context);
            var scopeStart = scope.startScope();

                var scopeTry = scope.startTry();
                    var list = web.get_lists().getByTitle("Documents");
                    context.load(list);
                scopeTry.dispose();

                var scopeCatch = scope.startCatch();

                    console.log("Catch: Could create list here");

                scopeCatch.dispose();

                var scopeFinally = scope.startFinally();
                    console.log("Finnaly: Try and load the list again if created in catch");
                scopeFinally.dispose();           

            scopeStart.dispose()


            context.executeQueryAsync(function() {
                if (scope.get_hasException() == true) {
                    console.log("Does not exists")
                }
                else {
                    console.log("Exists");
                }
            }, function() {  });
        }
        catch (ex) {
            console.log(ex.message);
        }
    }
share|improve this answer
    
An interesting idea –  Vadim Gremyachev Jun 13 at 18:04
    
Yes, looks to be good idea will try this sometime. –  user117048 Jun 13 at 18:32

ScopeHandling in a good way. Here's an alternate way to do recursive call for all sub webs and sub sub webs.

var context = new SP.ClientContext.get_current();
var web = context.get_web();
var rootWeb = context.get_site().get_rootWeb();

context.load(rootWeb);
context.executeQueryAsync(
   function () {
      var docLibrary = rootWeb.get_lists().getByTitle('Documents');
      if (docLibrary) {
          window.console && console.log("Root Web Contains Documents Lib: Title: " + rootWeb.get_title());
      }
   },
   function (sender, args) {
       window.console && console.log('Request failed: ' + args.get_message() + '\n' + args.get_stackTrace());
   }
);

getSubWebs(web);

function getSubWebs(web) {

    var subWebs = web.getSubwebsForCurrentUser(null);

    context.load(subWebs);
    context.executeQueryAsync(
        function () {
            var webEnumerator = subWebs.getEnumerator();

            while (webEnumerator.moveNext()) {

                var oWeb = webEnumerator.get_current();

                var obj = {
                    title: oWeb.get_title(),
                    url: oWeb.get_serverRelativeUrl()
                };

                var docLibrary = oWeb.get_lists().getByTitle('Documents');
                if (docLibrary) {
                    window.console && console.log("Contains Documents Lib: Title: " + obj.title + " , Url: " + obj.url);
                }

                //Recursive Call
                getSubWebs(oWeb);
            }
        },
        function (sender, args) {
            window.console && console.log('Request failed: ' + args.get_message() + '\n' + args.get_stackTrace());
        }
    );
}
share|improve this answer

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.