3

I'm running into an issue where I'm trying to modify a metadata field on a document within a document library. My code, will check out the document, update the metadata field and then check in the document. When I execute this code for the first time everything works fine, but when I run the code after that I get the version conflict error.

Please help...

Here is my code:

function SaveDocumentRequiredSignatureChange(ListItemId, AttachmentLibraryName,
                                             ckbControl, FileUrl) {
//debugger;
var SignatureRequired = (ckbControl.checked == true) ? '1' : '0';
spCtx = new SP.ClientContext.get_current();
spList = spCtx.get_web().get_lists().getByTitle(AttachmentLibraryName);
attachedDocumentUrl = FileUrl;
attachDocument = spCtx.get_web().getFileByServerRelativeUrl(attachedDocumentUrl);
attachDocument.checkOut();
spCtx.load(attachDocument);
spCtx.executeQueryAsync();


var spListItem = spList.getItemById(ListItemId);
spListItem.refreshLoad();
spCtx.load(spListItem);
spCtx.executeQueryAsync();

var workItem = spListItem;

workItem.set_item('SignatureRequired', SignatureRequired);
workItem.update();
spCtx.load(workItem)
//attachDocument.checkIn("File Update: Signature Required was modified.", 2);
//spCtx.load(attachDocument);
spCtx.executeQueryAsync(Function.createDelegate(this, this.onRequireSignatureQuerySucceeded), 
                          Function.createDelegate(this, this.onRequireSignatureQueryFailed))
}

/* onRequireSignatureQuerySucceeded() */
function onRequireSignatureQuerySucceeded() {
    spCtx = new SP.ClientContext.get_current();
    var attachDocument = spCtx.get_web().getFileByServerRelativeUrl(attachedDocumentUrl);
    attachDocument.checkIn();
    spCtx.load(attachDocument);
    spCtx.executeQueryAsync();
}
function onRequireSignatureQueryFailed(sender, args) {
    alert("Your request failed. Why? \n" + args.get_message() + "\n More Info: " + 
                                                           args.get_stackTrace());
}

I'm still getting the error and a new one...The file is checked out to the current logged in user. I added a rest call to get the hidden version number and added one to the count.Here is my code updates:

function SaveDocumentRequiredSignatureChange(ListItemId, AttachmentLibraryName, ckbControl, FileUrl) {
debugger;
var SignatureRequired = (ckbControl.checked == true) ? '1' : '0';
spCtx = new SP.ClientContext.get_current();
spList = spCtx.get_web().get_lists().getByTitle(AttachmentLibraryName);
attachedDocumentUrl = FileUrl;
attachDocument = spCtx.get_web().getFileByServerRelativeUrl(attachedDocumentUrl);
attachDocument.checkOut();
spCtx.load(attachDocument);
spCtx.executeQueryAsync();

spListItem = spList.getItemById(ListItemId);
spCtx.load(spListItem);
spCtx.executeQueryAsync();

spListItem.set_item('SignatureRequired', SignatureRequired);
spListItem.set_item('owshiddenversion', GetCurrentVersion(ListItemId));
spListItem.update();

spCtx.executeQueryAsync(Function.createDelegate(this, this.onRequireSignatureQuerySucceeded), Function.createDelegate(this, this.onRequireSignatureQueryFailed))

}

/* onRequireSignatureQuerySucceeded() */ function onRequireSignatureQuerySucceeded() { spCtx = new SP.ClientContext.get_current(); attachDocument = spCtx.get_web().getFileByServerRelativeUrl(attachedDocumentUrl); attachDocument.checkIn("File Update: Signature Required was modified.", 0); spCtx.load(attachDocument); spCtx.executeQueryAsync(); } function onRequireSignatureQueryFailed(sender, args) { alert("Your request failed. Why? \n" + args.get_message() + "\n More Info: " + args.get_stackTrace()); }

function GetCurrentVersion(ListItemId) { var versionCount = 0; var listServiceUrl = _spPageContextInfo.webServerRelativeUrl + "/_vti_bin/ListData.svc/DocLib?&$filter=Id eq " + ListItemId + "";

$.getJSON(listServiceUrl, { format: "json" })
      .done(function (data) 
        {
           $.each(data.d.results, function (i, result) {
                versionCount = result.Owshiddenversion;
            });   
        }
       )
      .fail(function () { alert("error") });

      return versionCount;

}

I've updated the code, but I'm still getting error. I thought by calling the getItemById a second time I hope that issue would go away, but it didn't. Please help:

var attachedDocumentUrl = null; function SaveDocumentRequiredSignatureChange(FileUrl, ListItemId, LibraryName, CkbCtrl) {

    var SignatureRequired = (CkbCtrl.checked == true) ? '1' : '0';
    spCtx = new SP.ClientContext.get_current();
    debugger;
    attachedDocumentUrl = FileUrl
    attachDocument = spCtx.get_web().getFileByServerRelativeUrl(attachedDocumentUrl);
    attachDocument.checkOut();
    spCtx.load(attachDocument);
    spCtx.executeQueryAsync();

    var spList = spCtx.get_web().get_lists().getByTitle(LibraryName);
    var spListItem = spList.getItemById(ListItemId);
    spCtx.load(spListItem);
    spCtx.executeQueryAsync();

    //var versionCount = spListItem.get_item('owshiddenversion');
    //spCtx.executeQueryAsync();
    //this.spListItem.set_item('owshiddenversion', versionCount + 1);

    spListItem.set_item('SignatureRequired', SignatureRequired);
    spListItem.update();
    spCtx.executeQueryAsync();

    spListItem = spList.getItemById(ListItemId);
    spCtx.load(spListItem);
    spCtx.executeQueryAsync(Function.createDelegate(this, this.onRequireSignatureQuerySucceeded), Function.createDelegate(this, this.onRequireSignatureQueryFailed))
}

/* onRequireSignatureQuerySucceeded() */
function onRequireSignatureQuerySucceeded() {
    debugger;
    spCtx = new SP.ClientContext.get_current();
    attachDocument = spCtx.get_web().getFileByServerRelativeUrl(attachedDocumentUrl);
    attachDocument.checkIn("File Update: Signature Required was modified.", 0);
    spCtx.load(attachDocument);
    spCtx.executeQueryAsync();
}
function onRequireSignatureQueryFailed(sender, args) {
    alert("Your request failed. Why? \n" + args.get_message() + "\n More Info: " + args.get_stackTrace());
}

2 Answers 2

2

Imagine you and I both open the edit form of a list item. You update a client's address, and I update his phone number. You hit the save button first, and I hit it a few seconds later. What should happen when I hit save? Should the old client address present on my edit form overwrite your change and set it back to the old value?

Actually, SharePoint will know this post is for a stale list item, and will fail with the version conflict message. It knows it is a stale version because of a hidden input on the edit form with an ID of "owshiddenversion". It checks the value of that form field against the current version, and throws the error if it does not match.

The same thing happens when you update a list item programmatically. When you submit the change via ExecuteQueryAsync, you are sending a field value for owshiddenversion under the covers. So as you've seen, the request will work the first time but will fail on subsequest posts.

To get around this you'll need to explicitly increment the value of owshiddenversion to "trick" SharePoint into accepting that it is receiving fresh list item data.

workItem.set_item('owshiddenversion', someValueThatYouHaveToFigureOut);

The values are not exactly inuitive to guess, though. They do not correspond to the version numbering seen in the UI. It seems they depend on the versioning settings on the list, so you'll need to play around with the field for awhile to ascertain the proper value to put into that field. I would suggest making some metadata updates manually and observe how that affects the hidden version field in the edit form.

4
  • See I was thinking if I call the refreshLoad() function that would do it? Am I wrong? Commented Sep 15, 2014 at 16:09
  • I'm not sure...I've never used RefreshLoad. And the documentation on it does not seem very helpful either. I had this situation once before but I was using asmx/SPServices and I used the approach above. Commented Sep 15, 2014 at 17:49
  • When I get the owshiddenversion value from the library and set it's value in code, after the executeQueryAsync I still get version conflict issue. Can you help me understand how you used the SPServices to get around this issue? Commented Sep 15, 2014 at 18:04
  • I took a closer look at the way we did it on a previous project, and we actually re-queried the list item and fetched the owshiddenversion that way. I'd like to get the solution posted up here, but I need to decouple some client-specific logic and it may be awhile before I get to that. I think we did it that way for expediency but I'm sure there's a way to guess what the version may be. Commented Sep 16, 2014 at 14:19
1

I had the same problem and used the suggestion from Brandon in the above comments to get rid of it: Just call

spListItem.refreshLoad();

before updating the item.

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.