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'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.

share|improve this question
    
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 May 8 '13 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 –  jasonscript May 8 '13 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 May 8 '13 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. –  jasonscript May 8 '13 at 9:43
    
Okay just before the enumerator using a breakpoint JSON.stringify(itemCollection) to serialise the output in the console window. –  Hugh Wood May 8 '13 at 9:54

1 Answer 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);
    }
share|improve this answer
    
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 May 8 '13 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 –  jasonscript May 8 '13 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 May 8 '13 at 8:58
    
will this work? –  Shawn May 8 '13 at 11:52

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.