1
votes

I am using JSOM to look up the value in a particular field of a particular item in a particular list. Overall, the code looks for the user's group membership (using SPServices), then uses that value to match an item in a list (list contains 'Title' field populated with group names and a 'Portal' field that contains another string) and tries to pull a different value from that list item. The error I get is on the line 'var listItemEnumerator = this.listItems.getEnumerator();'. The error is "The collection has not been initialized. It has not been requested or the request has not been executed. It may need to be explicitly requested."

Here is the code:

function getPortalURL(userGroup) {
     var URL = "";

     var ctx = new SP.ClientContext.get_current();
     var list = ctx.get_web().get_lists().getByTitle('Clients');

     var query = "<View><Query><Where><Eq><FieldRef Name='Title'><Value Type='Text'>" + userGroup + "</Value></Eq></Where></Query></View>";
     var camlQuery = new SP.CamlQuery();
     camlQuery.set_viewXml(query);

     this.listItems = list.getItems(camlQuery);
     ctx.load(this.listItems);
     ctx.executeQueryAsync(Function.createDelegate(this, this.onQuerySucceeded(URL)), Function.createDelegate(this, this.onQueryFailed));

     return URL;
}
function onQuerySucceeded(URL) {
    var listItemEnumerator = this.listItems.getEnumerator();

    while (listItemEnumerator.moveNext()) {
        var currentItem = listItemEnumerator.get_current();

        URL = currentItem.get_item('Portal');
    }
}
function onQueryFailed(sender, args) {
    alert('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());
}

EDIT: I have updated my code to reflect the changes below, but now I am seeing the query fail on every attempt, always routing to the failure function. Here is the code in case I did something wrong in my implementation:

function getPortalURL(userGroup) {
    var query = "<View><Query><Where><Eq><FieldRef Name='Title'><Value Type='Text'>" + userGroup + "</Value></Eq></Where></Query></View>";

    getListItems('Clients', query,
        function(items) {
            if(items.get_count() === 1) {
                var item = items.getItemAtIndex(0);
                alert(item.get_item('Portal'));
            }
        },
        function(sender,args){
            alert('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());
        }
    );
}

function getListItems(listTitle, queryText, success, error) {
    var ctx = SP.ClientContext.get_current();
    var web = ctx.get_web();
    var list = web.get_lists().getByTitle(listTitle);
    var query = new SP.CamlQuery();
    query.set_viewXml(queryText);
    var items = list.getItems(query);
    ctx.load(items);
    ctx.executeQueryAsync(
      function() {
          success(items);
      },
      error
    );
}
1

1 Answers

0
votes

Some corrections (the error occurs probably due to 3rd item):

  • var ctx = SP.ClientContext.get_current(); //since new constructor is not needed
  • return statement have to be removed since SP.ClientContext.executeQueryAsync is async method
  • replace ctx.executeQueryAsync(Function.createDelegate(this, this.onQuerySucceeded(URL)), Function.createDelegate(this, this.onQueryFailed)); to ctx.executeQueryAsync(Function.createDelegate(this, this.onQuerySucceeded), Function.createDelegate(this, this.onQueryFailed)); since SP.ClientContext.executeQueryAsync accepts callback functions

I would recommend to utilize the following common method instead. It allows to load List Items by specifying List Title and CAML query:

function getListItems(listTitle,queryText, success,error){
    var ctx = SP.ClientContext.get_current();
    var web = ctx.get_web();
    var list = web.get_lists().getByTitle(listTitle);
    var query = new SP.CamlQuery();
    query.set_viewXml(queryText);
    var items = list.getItems(query);
    ctx.load(items);
    ctx.executeQueryAsync(
      function() {
          success(items);
      },
      error
    );
}

Usage

Load list items from Pages list and print first one:

getListItems('Pages','<View><Query/></View>',
   function(items){
       if(items.get_count() > 0) {
           var firstItem = items.getItemAtIndex(0);
           console.log(firstItem.get_item('Title'));
       }   
   },
   function(sender,args){
      console.log(args.get_message());
   }
);    

In your case since a specific item have to be found, the following example could be used:

getListItems('<List Title>','<Your query goes here>',
   function(items){
       if(items.get_count() === 1) {  //Is item found?
           var item = items.getItemAtIndex(0);
           console.log(item.get_item('<Field Name>'));
       }       
   },
   function(sender,args){
      console.log(args.get_message());
   }
);    

Update

There is a typo in query, the fixed query:

<View><Query><Where><Eq><FieldRef Name='Title'/><Value Type='Text'>" + userGroup + "</Value></Eq></Where></Query></View>