1

I'm having a problem with my javascript code that I am sure is to do with scope, but I can't figure out where I'm going wrong.

I'm trying to write a method that will allow me to retrieve items in a list. I've followed numerous examples online, but as I said, I think it is a scope issue.

My Code is below

It includes an spHelper IIFE (immediately invoked function expression - or self executing anonymous function) that sets up my context and has the success/failure functions.

Outside the IIFE, I make the function call.

/*
    IIFE code for retrieving sp lists
 */
var spHelper = (function ($, SP, rootSP) {
    var clientContext = new SP.ClientContext(rootSP);
    var publicfunctions = {};
    var itemCollection = {};

    var onSPQueryFailure = function(sender, args) {
        alert("Request failed. " + args.get_message() + "\n" + args.get_stackTrace());
    }

    var onListRetrieveSuccess = function(sender, args) {
        var html = "";
        var listItemEnumerator = itemCollection.getEnumerator();
        while (listItemEnumerator.moveNext()) {
            var oListItem = listItemEnumerator.get_current();
            html += "<li>" + oListItem.get_item("Title") + "</li>";
        }

        $("#AdditionalFilters").append("<ul>" + html + "</ul>");
    }

    publicfunctions.createRefiners = function (listName, include) {
        itemCollection = clientContext.get_web().get_lists().getByTitle(listName).getItems('');

        clientContext.loadQuery(itemCollection, include);
        clientContext.executeQueryAsync(onListRetrieveSuccess, onSPQueryFailure);
    }



    return publicfunctions;
}(jQuery, SP, "/sites/SDA"));

spHelper.createRefiners("Ref_Process_Group","Include(Id,Title)");

The code seems to execute until the var listItemEnumerator = itemCollection.getEnumerator() line. At that point I get an error:

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.

Because the query seems to be executing and loading the 'Success' method, I am sure it is some kind of scope issue in JavaScript but I have been going round in circles and can't work it out.

10
  • I boiled your code down to it's simplest version here jsfiddle.net/hughajwood/ZwJud using an ajax call to simulate the list call. The code does fall into scope but you aren't making a new version of the object for use so that's a consideration if you are using it more than once and could be a possible issue. Apart from that you need to stick a breakpoint on the loadQuery line and check to see if itemCollection is being instantiated there. If it is, stick one on the getEnumerator line and step through the code.
    – Hugh Wood
    Commented May 8, 2013 at 9:24
  • itemCollection starts as an empty object {} When I get to the clientContext.loadQuery(itemCollection) the itemCollection is initialised with some SharePoint fields (which are minimized so they have unfathomable names: $0_0 and $4_0) Later, in the successHandler, the itemCollection is still initialized with the SharePoint properties. I can't really step into it because it goes into the minimized SP.js files from SharePoint Commented May 8, 2013 at 9:30
  • In your web.config find the compilation tag and set debug to true, this way you can trace through. Also stick the break point on the Enumerator and then look at items does it loop through the while loop?
    – Hugh Wood
    Commented May 8, 2013 at 9:39
  • I don't have access to the web.config of the SharePoint server. The line with the enumerator throws an exception. I never get to the while loop. Commented May 8, 2013 at 9:43
  • Okay just before the enumerator using a breakpoint JSON.stringify(itemCollection) to serialise the output in the console window.
    – Hugh Wood
    Commented May 8, 2013 at 9:54

1 Answer 1

-1
var itemCollection = {};
itemCollection is an empty object on the error line.

Just give some thoughts, havn't try the code, would pass it as pamramater work?

clientContext.executeQueryAsync(function(sender, args){
 onListRetrieveSuccess(itemCollection);
}, onSPQueryFailure);

remove the global object (itemCollection), will this work?

 publicfunctions.createRefiners = function (listName, include) {
        var itemCollection = clientContext.get_web().get_lists().getByTitle(listName).getItems('');

        clientContext.loadQuery(itemCollection, include);

        clientContext.executeQueryAsync(function(sender, args){
            var html = "";
            var listItemEnumerator = itemCollection.getEnumerator();
            while (listItemEnumerator.moveNext()) {
                var oListItem = listItemEnumerator.get_current();
                html += "<li>" + oListItem.get_item("Title") + "</li>";
            }

            $("#AdditionalFilters").append("<ul>" + html + "</ul>");
        }, onSPQueryFailure);
    }
4
  • There are several reasons why this code on the face of it won't work properly, but there could also be other reasons on top of this which will make working through this code difficult. Your solution is bypassing any broken scope that Jason is facing without fixing the real problem.
    – Hugh Wood
    Commented May 8, 2013 at 8:40
  • @Shawn Where the error is occurring (itemCollection.getEnumerator()) the itemCollection is not an empty object. Looking at it in IE Developer toolbars, it is {..} but unfortunately the contents are minimized so I can't really tell what is available Commented May 8, 2013 at 8:50
  • Jason you can add the variable to the watch, the best way would be to stick breakpoints in the code, run it through and find out, with the item in the watch. You can also then run tests on the objects in the console as an immediate window.
    – Hugh Wood
    Commented May 8, 2013 at 8:58
  • will this work?
    – Shawn
    Commented May 8, 2013 at 11:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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