Sunday, January 13, 2019

Resco Mobile CRM Tricks – Implement pagination in Resco Mobile CRM query - Javascript

Due to the server performance constrains Resco Mobile CRM returns 500 records only when we executing the query. There is no available setting to break that limitations. However to retrieve all the records we need then we have to implement the pagination for the query execution. Resco queries are execute in asynchronous way. We have to make sure we retrieve all the records before we proceed further.
We can follow followings steps to retrieve all records using pagination.

  
     1. Retrieve count of all the records we have to retrieve and set that value in global variable
In my case I have to retrieve all the answers belongs to the set of questions. I create fetch xml and retrieve answers count then determine how many pages need to be retrieved. After calculate the pages then built query need to retrieve data from the answers entity.


var NumberOfAnswerPages = 0;
var DataPagingSize = 500;
var ResultAnswers = [];

function GetAllAnswersCountByQuestions() {
 NumberOfAnswerPages = 0;
 Result_Ans = [];
 var FetchXml_Ans = "<fetch resultformat='DynamicEntities' version='1.0' output-format='xml-platform' mapping='logical' no-lock='true' aggregate='true' returntotalrecordcount='true' >" +
  "<entity name='new_answers'>" +
  "<attribute name='new_answersid' alias='recordcount' aggregate='count'  />" +
  "<filter type='and'>" +
  "<condition attribute='new_questionsid' operator='in'>";
  for (var qIndex = 0; qIndex < QuestionsArray.length; qIndex++) {
   FetchXml_Ans = FetchXml_Ans + "<value  uitype='new_questions'>" + QuestionsArray[qIndex].id + "</value>";
  }
 FetchXml_Ans = FetchXml_Ans + "</condition></filter></entity></fetch>";

 MobileCRM.FetchXml.Fetch.executeFromXML(FetchXml_Ans,
  function (data) {                    

   if (data != null && data != undefined && data.length > 0) {                        
    var recordsCount = data[0].properties["recordcount"];

    if (recordsCount > 0) {
     NumberOfAnswerPages = recordsCount / DataPagingSize;
     var questionIds = [];
     for (var qIndex = 0; qIndex < QuestionsArray.length; qIndex++) {
      questionIds.push(QuestionsArray[qIndex].id);
     }

     var answers = new MobileCRM.FetchXml.Entity('new_answers');
     answers.addAttribute('new_answersid');
     answers.addAttribute('new_name');
     answers.addAttribute('createdon');
     answers.addAttribute('new_questionsid');
     answers.addAttribute('new_answercrmvalue');
     answers.orderBy("new_order", true);

     var filter = new MobileCRM.FetchXml.Filter();
     filter.isIn("new_questionsid", questionIds);
     answers.filter = filter;

     var fetch = new MobileCRM.FetchXml.Fetch(answers);
     fetch.count = DataPagingSize;
     fetch.page = 1;

     ExecuteAnswerPaggingFetch(fetch, 1);

    } else {
     Result_Ans = [];
     //Do The Rest
    }

   } else {
    Result_Ans = [];
    //Do The Rest
   }
  },
  function (error) {
   MobileCRM.bridge.alert("Answer Records Retrieving Error : " + error);
   removePanels();
  }, null);
}


      2. Recursively call the data retrieval method and execute other methods after complete the data extraction. This will help to synchronize method flow even Resco execute data retrieval asynchronously. 

function ExecuteAnswerPaggingFetch(fetch, page, success) {
 fetch.page = page;
 fetch.execute("DynamicEntities", function (res) {
  if (res != null && typeof res != 'undefined' && res.length > 0) {
   for (var i = 0; i < res.length; i++) {
    ResultAnswers.push(res[i]);
   }
  }

  if (page > NumberOfAnswerPages) {
   //Now data retrieval is completed call next set of methods
   return;
  }

  ExecuteAnswerPaggingFetch(fetch, page += 1);
 }, MobileCRM.bridge.alert, null);
}