This project has moved and is read-only. For the latest updates, please go here.

UpdateListItems Completefunc

Aug 19, 2014 at 11:44 PM
Hi All:

I am having issues with updatelistitems not storing records. I have a custom .aspx page that resides on the same Sharepoint site as the list I am writing to. For most users, everything fires properly and the new list item is stored. However, a handful of users are reporting that they receive a success message but the item cannot be found in the list. Here's the code I am using:
function saveRecord(chkType,recordID,csrname,srnumber,sitenumber,delivered,deliveredtime,damage,damagedet,location,locationdelay,locationinstalldelay,locationdelaydet,siteready,sitereadydelay,sitereadydet,software,softwaredelay,softwaredet,hotseat,hotseatdet,otherissues,otherissuesdelay,otherissuesdet,guide,guidedet,instDate1,trip1lunch,trip1breaks,arrTrip1,compTrip1,timeOnSite1,instDate2,trip2lunch,trip2breaks,arrTrip2,compTrip2,timeOnSite2,instDate3,trip3lunch,trip3breaks,arrTrip3,compTrip3,timeOnSite3,instDate4,trip4lunch,trip4breaks,arrTrip4,compTrip4,timeOnSite4,instDate5,trip5lunch,trip5breaks,arrTrip5,compTrip5,timeOnSite5,instDate6,trip6lunch,trip6breaks,arrTrip6,compTrip6,timeOnSite6,instDate7,trip7lunch,trip7breaks,arrTrip7,compTrip7,timeOnSite7,visitnum) {

  if (recordID == "") {
    var batchType = "New";
    var batchMsg = "Added";
  } else {
    if (chkType == 0){
        var batchType = "Update";
        var batchMsg = "Saved";
    } else if (chkType == 1){
        var batchType = "Update";
        var batchMsg = "Submitted";
      operation: "UpdateListItems", 
      async: false, 
      batchCmd: batchType,
      listName: "ecoATM Installation Survey",
      ID: recordID,
      valuepairs: [['CSR', csrname],
                    ['Title', srnumber], 
                    ['SiteNumber', sitenumber],
                    ['InstallTrips', visitnum],
                    ['KioskDelivery', delivered],
                    ['KioskDeliveryTime', deliveredtime],
                    ['Damage', damage],
                    ['DamageDetails', damagedet],
                    ['KioskLocation', location],
                    ['LocationDelay', locationdelay],
                    ['DelayTime', locationinstalldelay],
                    ['LocationDelayDetails', locationdelaydet],
                    ['SiteReadyforInstall', siteready],
                    ['SiteReadyDelay', sitereadydelay],
                    ['SiteReadyDetails', sitereadydet],
                    ['SoftwareIssues', software],
                    ['SoftwareIssuesDelay', softwaredelay],
                    ['SoftwareIssuesDetails', softwaredet],
                    ['ecoATMHotSeat', hotseat],
                    ['ecoATMHotSeatDetails', hotseatdet],
                    ['OtherIssues', otherissues],
                    ['OtherIssuesDelay', otherissuesdelay],
                    ['OtherIssuesDetails', otherissuesdet],
                    ['InstallGuideMatch', guide],
                    ['InstallationGuideDetails', guidedet],
                    ['InstallDateTrip1', instDate1],
                    ['Trip1Lunch', trip1lunch],
                    ['Trip1Breaks', trip1breaks],
                    ['ArriveTimeTrip1', arrTrip1],
                    ['CompletionTimeTrip1', compTrip1],
                    ['Trip1TotalTime', timeOnSite1],
                    ['InstallDateTrip2', instDate2],
                    ['Trip2Lunch', trip2lunch],
                    ['Trip2Breaks', trip2breaks],
                    ['ArriveTimeTrip2', arrTrip2],
                    ['CompletionTimeTrip2', compTrip2],
                    ['Trip2TotalTime', timeOnSite2],    
                    ['InstallDateTrip3', instDate3],
                    ['Trip3Lunch', trip3lunch],
                    ['Trip3Breaks', trip3breaks],
                    ['ArriveTimeTrip3', arrTrip3],
                    ['CompletionTimeTrip3', compTrip3],
                    ['Trip3TotalTime', timeOnSite3],
                    ['InstallDateTrip4', instDate4],
                    ['Trip4Lunch', trip4lunch],
                    ['Trip4Breaks', trip4breaks],
                    ['ArriveTimeTrip4', arrTrip4],
                    ['CompletionTimeTrip4', compTrip4],
                    ['Trip4TotalTime', timeOnSite4],
                    ['InstallDateTrip5', instDate5],
                    ['Trip5Lunch', trip5lunch],
                    ['Trip5Breaks', trip5breaks],
                    ['ArriveTimeTrip5', arrTrip5],
                    ['CompletionTimeTrip5', compTrip5],
                    ['Trip5TotalTime', timeOnSite5],
                    ['InstallDateTrip6', instDate6],
                    ['Trip6Lunch', trip6lunch],
                    ['Trip6Breaks', trip6breaks],
                    ['ArriveTimeTrip6', arrTrip6],
                    ['CompletionTimeTrip6', compTrip6],
                    ['Trip6TotalTime', timeOnSite6],
                    ['InstallDateTrip7', instDate7],
                    ['Trip7Lunch', trip7lunch],
                    ['Trip7Breaks', trip7breaks],
                    ['ArriveTimeTrip7', arrTrip7],
                    ['CompletionTimeTrip7', compTrip7],
                    ['Trip7TotalTime', timeOnSite7],    
                    ['ChecklistComplete', chkType]],
      completefunc: function(xData, Status) { 
            //alert( xData.responseText );
            if (Status == "Error") {
               alert ("Unable to communicate with Sharepoint Server.  Please try again at a later time.");
            } else if ($(xData).hasSPError()) {
                alert("An Error Has Occurred. Sharepoint Error: " + $(xData).getSPError());
            } else {
                alert("The record was " + batchMsg + " successfully.");
Here's the code that I found on codeplex for the error checking:
jQuery.fn.hasSPError = function() {
    var spErrCode = $(this).find("[nodeName='ErrorCode']:first");
    if (spErrCode.size()
        &&  spErrCode.text() !== "0x00000000") {
        return true;
    } else {
        spErrCode = $(this).find("[nodeName='faultcode']");
        if (spErrCode.size()) {
            return true;
    return false;

jQuery.fn.getSPError = function(){
    var error = "ERROR: Call to Sharepoint Web Services failed.";
    if ($(this).find("[nodeName='ErrorCode']").size()) {
        error += "\n" + $(this).find("[nodeName='ErrorCode']:first").text()
            +   ": " + $(this).find("[nodeName='ErrorText']").text();
    } else if ($(this).find("[nodeName='faultcode']").size()) {
        error += $(this).find("[nodeName='faultstring']").text()
            + "\n" + $(this).find("[nodeName='errorstring']").text();
    } else {
        error = "";
    return error;
After troubleshooting today, one of the calculated fields in the form was returning NaN for the value and it looks like this was preventing the form from storing. However, since it did not meet any of the logic for the completefunc error checking, the form was returning a "success" message.

Any ideas on how I can change the error logic to capture when the item is not recording properly?

Thanks for any help you can give.

Aug 20, 2014 at 2:58 AM

Without testing the hasSPError code (which I can't recall ever seeing before), I'm sure that it's invalid data causing you the problem. You're trying to write a large number of values, and it's likely that somewhere upstream you have an issue somewhere.

Rather than using so many individual variables, I'd suggest that you build up a JavaScript object with all the values. This will make it easier to spot the data issues in your debugging and also easier to maintain.

Aug 20, 2014 at 1:26 PM
Hi Marc:

Thanks for responding. I will do as you suggested and build the Javascript object to hold the values. However, since the error was caused by the NaN value in the calculated field, do you know how Sharepoint responds to an invalid value for a field type of number? I guess I could turn on debugging, but I am not very familiar with capturing the soap header that is returned by the spservices call.

Thanks again!

Aug 20, 2014 at 1:55 PM
If you had NaN in a calculated field, then I'd suggest you adapt the formula to handle that situation. That type of value will cause the write to fail.

When you do an UpdateListItems, you get back an exact copy of what was just written if the write was successful. That's how you can be assured the write worked.

Oct 11, 2014 at 10:55 PM
sympmarc wrote:
Without testing the hasSPError code (which I can't recall ever seeing before),

Hey Mark,

This is the thread where the error handling code came from.

Do you think something like this could be built into future releases to simplify error checking in SPServices?
Oct 15, 2014 at 2:34 PM
Unfortunately, that code will only work with some of the operations, as I mentioned in the other thread. There's just too much inconsistency in the SOAP Web Services. However, Paul's work there is valid; it just won't catch all errors.

That said, I'll look at adding Paul's functions in the next version.