Question

Hi Sharepoint experts,

I'm trying to add list item using jsom and succeeded but my code keeps adding empty list item first.

    function repeat(pattern, count) {
        if (count < 1) return '';
        var result = '';
        while (count > 1) {
            if (count & 1) result += pattern;
            count >>= 1, pattern += pattern;
        }
        return result + pattern;
    }

    function onCountSucceeded() {
        varNoPR = '';
        varListCnt = oList.get_itemCount();
        if (varListCnt === 0) {
            varListCnt = 1;
        }
        else {
            varListCnt += 1;
        }
        varTmpStr = varListCnt.toString();
        varStrLen = varTmpStr.length;
        varNoPR = repeat('0', 10 - varStrLen).concat(varTmpStr);
     }

    function getLastNumber() {
        var clientContext2 = new SP.ClientContext(varsiteUrl);
        this.oList = clientContext2.get_web().get_lists().getByTitle(listName);
        clientContext2.load(this.oList);    
        clientContext2.executeQueryAsync(
            Function.createDelegate(this, this.onCountSucceeded),
            Function.createDelegate(this, this.onQueryFailed)
        );    
    }

    function createItem() {  
        var clientContext = new SP.ClientContext(varsiteUrl);
        var oList = clientContext.get_web().get_lists().getByTitle(listName);

        var itemCreateInfo = new SP.ListItemCreationInformation();
        this.oListItem = oList.addItem(itemCreateInfo);
        oListItem.set_item('Title', 'My New Item!');
        oListItem.set_item('NoPR', varNoPR);
        oListItem.update();

        clientContext.load(oListItem);
        clientContext.executeQueryAsync(
            Function.createDelegate(this, this.onAddItemSucceeded),
            Function.createDelegate(this, this.onQueryFailed)
        );
    }

    function createListItem() {
        getLastNumber();
        createItem();
    }

So my goal is inserting custom auto increment number by counting the list items first and then add '0' so the resulting number becomes '0000000001', ...etc. But when I run this twice (I assigned this code to button), it resulted in empty item, and then item 0000000001. What I am doing wrong here ?

Thanks for any help...

Was it helpful?

Solution

The problem is that the calls are async, so you should make sure getLastNumber() is done before you call createItem(). This could be done in diferrent ways, but an easy route is to use jQuerys $.Deferred object.

An simple example based on your getLastNumber and createListItem:

function getLastNumber() {
        this.dfd = $.Deferred();

        var clientContext2 = new SP.ClientContext(varsiteUrl);
        this.oList = clientContext2.get_web().get_lists().getByTitle(listName);
        clientContext2.load(this.oList);    
        clientContext2.executeQueryAsync(
            Function.createDelegate(this, this.onCountSucceeded),
            Function.createDelegate(this, this.onQueryFailed)
        );    

        return this.dfd.promise();
    }

   function onCountSucceeded() {
    varNoPR = '';
    varListCnt = oList.get_itemCount();
    if (varListCnt === 0) {
        varListCnt = 1;
    }
    else {
        varListCnt += 1;
    }
    varTmpStr = varListCnt.toString();
    varStrLen = varTmpStr.length;
    varNoPR = repeat('0', 10 - varStrLen).concat(varTmpStr);

    this.dfd.resolve();
 }


      function createListItem() {
         getLastNumber().done(function() {
           createItem();
        });     
      }

OTHER TIPS

Welcome to the SharePoint SE!

This behavior occurs since SP.ClientContext.executeQueryAsync method is an async method. Hence you cant call your methods sequentially like this:

getLastNumber();
createItem();

but have to wait until succeededCallback function will be invoked and only then execute the next request.

When working with asynchronous API such as JSOM the following patterns are commonly used:

  • Using nested callbacks
  • Using the promises pattern

Please refer Asynchronous programming in apps for Office article to get acquainted with asynchronous programming for SharePoint.

The below example is converted version of your example using callback approach:

function repeat(pattern, count) {
        if (count < 1) return '';
        var result = '';
        while (count > 1) {
            if (count & 1) result += pattern;
            count >>= 1, pattern += pattern;
        }
        return result + pattern;
}




function getNextNumber(listTitle,OnSuccess,OnError) {
    var context = SP.ClientContext.get_current();
    var list = context.get_web().get_lists().getByTitle(listTitle);
    context.load(list);    
    context.executeQueryAsync(
        function(){
               var nextIdStr = (list.get_itemCount() + 1).toString();
               var nextNoPR = repeat('0', 10 - nextIdStr.length).concat(nextIdStr);
               OnSuccess(nextNoPR);
        },
        OnError
    );    
}





function addListItem(listTitle,itemProps,OnItemAdded,OnItemFailed)
{
    var context = SP.ClientContext.get_current();
    var web = context.get_web();

    var list = web.get_lists().getByTitle(listTitle);
    var itemCreateInfo = new SP.ListItemCreationInformation();
    var listItem = list.addItem(itemCreateInfo);

    for(var propName in itemProps) {
       listItem.set_item(propName, itemProps[propName]) 
    }

    listItem.update();
    context.load(listItem);
    context.executeQueryAsync(
        function() {
          OnItemAdded(listItem);           
        },
        OnItemFailed
    );
}

Usage

var listTitle = 'Requests';
getNextNumber(listTitle,
  function(nextNoPR){
      //console.log(nextNoPR);

      var itemProperties  = {'Title': 'New request','NoPR':nextNoPR};
      addListItem(listTitle,itemProperties,
         function(item){   
            console.log(item.get_item('NoPR'));
         },
         function(sender,args){
            console.log(args.get_message());
         }
      );
  },
  function(sender,args){
      console.log('An error corrured while getting next NoPR:' + args.get_message());
  }
);
Licensed under: CC-BY-SA with attribution
Not affiliated with sharepoint.stackexchange
scroll top