Lists.GetListItemChangesSinceToken Not working on SharePoint 2007

Sep 24, 2013 at 10:01 PM
Hi Marc...

So, as the last discussion item I opened indicates, I have been playing with GetListItemChangesSinceToken, which may soon replace my use of GetListItems... This method (GetListItemChangesSinceToken) works fine in SP2010 and 2013, but is failing for me when I try it in SP2007...

Below I have the request and response (XML) along with the SPServices call I'm issuing... I know this, is is against 2007.. I'm hopping you may still have an environment to try this on...

Request:

SPServices:

$().SPServices({
    operation: 'GetListItemChangesSinceToken',
    listName: 'PaulTestList',
    completefunc: function(xData, status){
        console.log('back!');
    }
})

XML Request:

<soap:Envelope xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
xmlns:xsd='http://www.w3.org/2001/XMLSchema'
xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'>
  <soap:Body>
    <GetListItemChangesSinceToken xmlns='http://schemas.microsoft.com/sharepoint/soap/'>
      <listName>PaulTestList</listName>
      <viewName></viewName>
      <query></query>
      <viewFields></viewFields>
      <rowLimit></rowLimit>
      <queryOptions></queryOptions>
      <changeToken></changeToken>
      <contains></contains>
    </GetListItemChangesSinceToken>
  </soap:Body>
</soap:Envelope>

Response from SharePoint 2007

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <soap:Body>
    <soap:Fault>
      <faultcode>soap:Server</faultcode>
      <faultstring>Exception of type
      'Microsoft.SharePoint.SoapServer.SoapServerException' was
      thrown.</faultstring>
      <detail>
        <errorstring xmlns="http://schemas.microsoft.com/sharepoint/soap/">
        Input string was not in a correct format.</errorstring>
      </detail>
    </soap:Fault>
  </soap:Body>
</soap:Envelope>
Coordinator
Oct 4, 2013 at 8:36 PM
Paul:

I just rigged something up to test this and I get the same error you did. Did you get it working?

In doing this, I also got a test for GetListItemChanges running, which does work in 2007, but it took some fiddling to get all the syntax right. For instance, I think you have to specify a contains value.

M.
Oct 4, 2013 at 9:04 PM
Thanks Marc for trying... I wanted to see if it was my SP env. or if it was common in others... sounds as if this operation does not work in SP2007... Works great in SP2010 and 2013... and I'm really liking its behavior...

I did look into GetListItemChanges but decided to not use it since it is (IMO) limiting for my use case and has some a weird usage pattern (like the one you highlighted). I'm not sure we can use it with a full CAML Query... I was also did not like that the input parameters to that operation were different from the normal GetListItems.

Where am I:
I did not get this working on SP2007, but I already had my data using GetListItems, so I'm continuing to use that with SP2007... I have to do some funky stuff to get "changes" to the query, which is why I like this GetItemChangesSinceToken so much...

Thanks again for trying... Appreciate the help and post back.

Paul.
Coordinator
Oct 4, 2013 at 9:10 PM
If I don't pass anything in for the changeToken, I get a result. In other words, a blank token doesn't fly.
            case "GetListItemChangesSinceToken":
                addToPayload(opt, ["listName",
                "viewName",
                ["query", "CAMLQuery"],
                ["viewFields", "CAMLViewFields"],
                ["rowLimit", "CAMLRowLimit"],
                ["queryOptions", "CAMLQueryOptions"],
//              "changeToken",
                "contains"]);
                break;
M.
Coordinator
Oct 4, 2013 at 9:22 PM
On the other hand, passing in a token does work:
    $(divId).html(waitMessage).SPServices({
        operation: "GetListItemChangesSinceToken",
        listName: "Sales Opportunities",
//      CAMLViewFields: "<ViewFields><FieldRef Name='Title' /></ViewFields>",
//      since: "2013-06-30T15:29:43Z",
        changeToken: "1;3;37920121-19b2-4c77-92ff-8b3e07853114;635165141627700000;31175",
        contains: "<Contains><FieldRef Name='StateID'/><Value Type='Text'>Dak</Value></Contains>",
        completefunc: function (xData, Status) {
            var out = $().SPServices.SPDebugXMLHttpResult({
                node: xData.responseXML,
                outputId: divId
            });
            $(divId).html("").append("<b>This is the output from the GetListItemChanges operation:</b>" + out);
        }
    });
It looks like for both GetListItemChanges and GetListItemChangesSinceToken, you can't pass empty "contains" elements or for the latter, an empty "changeToken" element.

I think I'll come up with a way to flag "add to payload only if non-null" elements for the addToPayload function.

You're right; this is a nice operation. You get the list schema plus all the items in one call. How are you planning to use it?

M.
Oct 4, 2013 at 10:07 PM
Marc,
That's great news... :)
So it looks like I might be able to only use the GetListItemChangesSinceToken regardless of SP Version... We may want to try the same Query (don't include the changeToken) on SP2010 and SP2013 just to make sure the behavior is the same (meaning: successful)... Sounds like SP2010 and 2013 tolerates an empty element since it works on those environments. I may be able to do this later tonight or this weekend if you can't...

What I'm working with:
I have had a "module" that provides data Queries that "persist" - meaning: after you get the query "Object" back, that query remains "alive" and monitoring for changes (using pull rather than push - since SP does not provide for websockets). I was using an ugly approach with GetListItems which had complexities around how to identify item(s) in the Query that no longer matched the criteria (CAML) and thus should be removed from the set... Getting the list of changed or new items was not difficult, but removes was an issue.
So I'm doing some refactoring into a more robust library... GetListItemChangesSinceToken is perfect for this module because it does a great job of identifying add/changes as well as deletion from the query. The library I have does more than monitoring the data, it also allows me to bind "listeners" (events) that are triggered when the Query changes and using knockout.js to provide the data as observableArray's and objects who values are observables as well.

As I mentioned, this module uses knockout.js - which ties the query (actually a Knockout.js observable Array with a few more custom methods) to the ViewModel (the HTML UI and thus you have a responsive UI. This works very well in Single Page Applications...

And... I enable this functionality by extending SPServices (without changing the library itself) to recognize a new input param called 'persist'.... When my code see that and if the operation is GetListItems or GetListItemChangesSinceToken, it handles the "Query".... If it does not see it, then it just lets it go to SPServices...

Paul.
Coordinator
Oct 4, 2013 at 10:09 PM
Very interesting. Do you think this is a good addition to SPServices itself?

M.
Oct 4, 2013 at 11:44 PM
Possibly. Depends on how suffisticated the users of SPServices want to get. Maybe it's an add-on. :)
My goal is to also adopt it to the new client side api's of SP - CSOM and REST.


--
Paul T.

-- Sent from Mobile