Value Objects Cannot Be Used Across Methods in a Query

SharePoint 2010

When you use a method or property to return a value or an object that inherits from the ClientValueObject class (JavaScript: ClientValueObject), you cannot use the value as a parameter for another method call in the same query.

Last modified: May 27, 2011

Applies to: SharePoint Foundation 2010

Available in SharePoint Online

For more information about value objects, see Client Objects, Value Objects, and Scalar Properties.

For example, suppose that you want to create a SharePoint list whose display name is same as the Web site’s title. If you are familiar with the SharePoint Foundation server object model, you might be tempted to write code as follows.

Incorrect Code

using System;
using Microsoft.SharePoint.Client;

namespace Microsoft.SDK.SharePointServices.Samples
{
    class CreateList
    {
        static void Main()
        {
            ClientContext clientContext = new ClientContext("http://MyServer/sites/MySiteCollection");
            Web oWebsite = clientContext.Web;

            ListCreationInformation listCreationInfo = new ListCreationInformation();
            listCreationInfo.TemplateType = 104;
            listCreationInfo.Title = oWebsite.Title;
            List oList = oWebsite.Lists.Add(listCreationInfo);

            clientContext.ExecuteQuery();
        }
    }
}

Compiling the code returns a PropertyOrFieldNotInitializedException because the "property or field has not been initialized". The example returns an exception because the Title property (JavaScript: title) of the Web site object is not available before you call ExecuteQuery(). While SQL allows you to declare a local variable that holds the Web site title and allows you to use the local variable in list creation, you cannot declare a local variable in the client object model. Therefore, you must call ExecuteQuery() or ExecuteQueryAsync(ClientRequestSucceededEventHandler, ClientRequestFailedEventHandler) (JavaScript: executeQueryAsync(succeededCallback, failedCallback)) twice, first to return the value of the Title property (JavaScript: title), and then to create the list, as seen in the following revised example.

Correct Code

function getWebSiteTitle() {
    this.clientContext = new SP.ClientContext('/sites/TestWebs/TestWeb1');
    this.oWebsite = clientContext.get_web();

    clientContext.load(oWebsite, 'Title');

    clientContext.executeQueryAsync(Function.createDelegate(this, this.createList), Function.createDelegate(this, this.onQueryFailed));    
}

function createList() {
    var listCreationInfo = new SP.ListCreationInformation();
    listCreationInfo.set_templateType(104);
    listCreationInfo.set_title(oWebsite.get_title());

    var oList = oWebsite.get_lists().add(listCreationInfo);

    clientContext.executeQueryAsync(Function.createDelegate(this, this.onQuerySucceeded), Function.createDelegate(this, this.onQueryFailed));
}

function onQuerySucceeded() {
    alert('List created.');
}

function onQueryFailed(sender, args) {
    alert('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());
}
Show: