Bluescrod
Bluescrod

Reputation: 79

How to browse to the next page in a datasource that is loaded into table in Google AppMaker

I'm working on a requirement where I have a datasource named 'emailSearchResults' where I search for email messages metadata and load the results in the datasource.

The fields in the datasource are not relevant, however I set the datasource to have 50 records per page as per the below screenshot: enter image description here

The script I used to load the datasource is shown in the query field, that call the following script:

function getMessageDetails(userId, msgID)
{
  var messageDetails = [];
  var messageData;
  var msgID_,subject_,from_,date_;

  messageData=Gmail.Users.Messages.get(userId,msgID,{format:"metadata", metadataHeaders:["Message-ID", "Subject", "From", "Date"]});

  console.log(messageData.payload.headers);

  //console.log(msgID);
  //console.log(messageData.payload.headers[3].value);

  date_="<na>";
  from_="<na>";
  subject_="<na>";
  msgID_="<na>";

  for (var counter =0;counter<4;counter++)
  {
    if (messageData.payload.headers[counter].name=="Message-ID")
    {
      msgID_=messageData.payload.headers[counter].value;
    }

    if (messageData.payload.headers[counter].name=="Subject")
    {
      subject_=messageData.payload.headers[counter].value;
    }

    if (messageData.payload.headers[counter].name=="From")
    {
      from_=messageData.payload.headers[counter].value;
    }

    if (messageData.payload.headers[counter].name=="Date")
    {
      date_=messageData.payload.headers[counter].value;
    }
  }

  messageDetails.push(date_);
  messageDetails.push(from_);
  messageDetails.push(subject_);
  messageDetails.push(msgID_);

  return messageDetails;
}


function searchMessages(userId,condition)
{
  //
  // first we build the conditions
  // we can make it fixed
  // or we can make it dynamic
  var searchResult;
  var deleteResult;
  var currentMessage;
  var results = [];
  var pageToken;
  var params = {};
  var _stat;
  var options = {
    includeSpamTrash: "true",
    pageToken: pageToken
  };
  var msgRecord = [];

  do
  {
    searchResult=Gmail.Users.Messages.list(userId,options);

    for (var i = 0; i < searchResult.messages.length; i++)
    {
      var record=app.models.emailSearchResults.newRecord();
      msgRecord=getMessageDetails(userId,searchResult.messages[i].id);

      record.msgMainID=searchResult.messages[i].id;
      record.msgID=msgRecord[3];
      record.subject=msgRecord[2];
      record.senderAddress=msgRecord[1];
      record.msgDate=msgRecord[0];

      /*console.log(searchResult.messages[i].id);
      console.log(msgRecord[3]);
      console.log(msgRecord[2]);
      console.log(msgRecord[1]);
      console.log(msgRecord[0]);

      return;*/
      results.push(record);
      msgRecord=null;
    }

    if (searchResult.nextPageToken) {
      options.pageToken = searchResult.nextPageToken;
    }
  } while (searchResult.pageToken);

  searchResult=null;

  return results;
}

On the main page I put a table and linked it to the datasource, and I enabled pagination on the table, so I get the pager buttons at the bottom of the table as below: enter image description here enter image description here

When I execute the app and the datasource is filled, I see the first page results in a correct way, however when I want to move to the next page, I click the next page button and once the loading is complete I find out that I still see the same results from the first page on the table.

I am not familiar with how to make the table show the results of the second page then the third page, and I am going in circles on this...

Hope the explanation is clear and addresses the issue..

I would really appreciate any help on this! Regards

Upvotes: 2

Views: 280

Answers (1)

The Support Group
The Support Group

Reputation: 343

Currently pagination isn't working as expected with calculated datasources. You can, however, build your own. There are several changes you'll need to make to accomplish this. First you'll want to refactor your searchMessages function to something like this:

function searchMessages(userId, pageToken){

  var results = [];
  var options = {
    includeSpamTrash: "true",
    pageToken: pageToken,
    maxResults: 50
  };

    var searchResult = Gmail.Users.Messages.list(userId, options);

    for (var i = 0; i < searchResult.messages.length; i++){
      var record = app.models.emailSearchResults.newRecord();
      var msgRecord = getMessageDetails(userId,searchResult.messages[i].id);

      record.msgMainID = searchResult.messages[i].id;
      record.msgID = msgRecord[3];
      record.subject = msgRecord[2];
      record.senderAddress = msgRecord[1];
      record.msgDate = msgRecord[0];

      results.push(record);
    }

  return {records: results, nextPageToken: searchResult.nextPageToken};
}

Then you'll want to change your datasource query. You'll need to add a number parameter called page.

var cache = CacheService.getUserCache();
var page = query.parameters.page || 1;
var pageToken;
if(page > 1){
  pageToken = cache.get('pageToken' + page.toString());
}

var results = searchMessages('me', pageToken);

var nextPage = (page + 1).toString();
cache.put('pageToken' + nextPage, results.nextPageToken);

return results.records;

You'll need to modify the pagination widget's various attributes. Here are the previous/next click functions:

Previous:

widget.datasource.query.pageIndex--;
widget.datasource.query.parameters.page = widget.datasource.query.pageIndex;
widget.datasource.load();

Next:

widget.datasource.query.pageIndex++;
widget.datasource.query.parameters.page = widget.datasource.query.pageIndex;
widget.datasource.load();

You should be able to take it from there.

Upvotes: 2

Related Questions