Search code examples
javascriptsharepointcaml

Large list retrieval in SharePoint list failing 4-10 times before working (JavaScript)


I need to copy items between lists (adding more stuff to each item so cant use flow), I am experiencing a error where if the source list is greater than 100 items, the script terminates at the query into the source list (first thing to happen on button click), for like 4-10 times then it works.

I am using promises to make sure everything happens in order but that doesn't seem to be the issue, but instead the query failing, in the first step in the promise structure.

Its not the rowlimit in the query, as that is set to a 1000, and the row count is around 200.

Here is an example code that works fine with small number of items but requires multiple runs when both lists contain about 100 items:

<head>
    <script
  src="https://code.jquery.com/jquery-3.3.1.js"
  integrity="sha256-2Kok7MbOyxpgUVvAk/HJ2jigOSYS2auK4Pfzbm7uH60="
  crossorigin="anonymous"></script>
    <script>

    function update() {
        console.log("1")
  var dfd = $.Deferred(function () {
    var updateBtnCLientContextForSourceList = 
      new SP.ClientContext.get_current();
    var getSourceList = updateBtnCLientContextForSourceList
        .get_web()
        .get_lists()
        .getByTitle("SourceList");
    var camlQueryForSourceList = new SP.CamlQuery();
    camlQueryForSourceList.set_viewXml('<View><Query><Where><Geq><FieldRef Name=\'ID\'/>' +
      '<Value Type=\'Number\'>1</Value></Geq></Where></Query><RowLimit>4000</RowLimit></View>');
    var SourceListtStore = getSourceList.getItems(camlQueryForSourceList);
    updateBtnCLientContextForSourceList.load(SourceListtStore);
    updateBtnCLientContextForSourceList.executeQueryAsync(
      function () {
        dfd.resolve(SourceListtStore);
      },
      function (sender, args) {
        dfd.reject(args);
      }
    );
  });
         console.log("2")
  return dfd.promise();
}

acadcount = 0;

function check() {
  update()
  .then(
    function (SourceListtStore) {
         console.log("3")
      acadcount = SourceListtStore.get_count()
         console.log("4")
      var dfd = $.Deferred(
        function () {
          var updateBtnCLientContextForWeeksAllocated = 
            SP.ClientContext.get_current();
          var getWeeksAllocated = 
            updateBtnCLientContextForWeeksAllocated
              .get_web()
              .get_lists()
              .getByTitle("Weeks Allocated");
          var camlQueryForWeeksAllocated = new SP.CamlQuery();
          camlQueryForWeeksAllocated.set_viewXml('<View><Query><Where><Geq><FieldRef Name=\'ID\'/>' +
            '<Value Type=\'Number\'>1</Value></Geq></Where></Query><RowLimit>1000</RowLimit></View>');
          var weeksAllocatedListStore = 
            getWeeksAllocated.getItems(camlQueryForWeeksAllocated);
          updateBtnCLientContextForWeeksAllocated.load(weeksAllocatedListStore);
          updateBtnCLientContextForWeeksAllocated.executeQueryAsync(
            function () {
              dfd.resolve(weeksAllocatedListStore);
            },
            function (sender, args) {
              dfd.reject(args);
            }
          );
        }
      );
         console.log("5")
      return dfd.promise()
    }
  ).then(
    function (waListStore) {
         console.log("6")
      if (waListStore.get_count() === acadcount) {
           console.log("7")
        alert("All items have been copied")
      }
      else {
           console.log("8")
        alert("Please try again")
      }
    }
  );
}

    </script>


</head>

<body>
    <button onClick="check()">Check</button>


</body>
  • stage 2=just before the return of the source list's query result

  • stage 5=just before the return of the weeks allocated list's query
    result

source list: 2 items, Weeks allocated:3 items

  • first & second run: up to 8(completed)

Source list: 109 items, Weeks allocated:1 item

  • First run: up to 2

  • 2,3: up to 5

  • 4: up to 2

  • 5-8: up to 5

  • 9:up to 8(completed)

Source list:109 items, weeks allocated:100 items

  • first 33 runs: up to 5

  • 34:up to 8(completed)

So am i correct in assuming that, when script fails, the promise.return is running before the .resolve is completed? if so how can i get around this?


Solution

  • The page was reloading before JS had a chance to execute completely with a large number of items, disabled refresh on button click and it now works fine.