0

I'm having some peculiar behaviour around doing something as simple as adding records to a List.

Initially I'm querying for a list of contacts and using Filters to reduce the size of the list. So, for example, I want to find Contacts that were created on a given date. A single day might return 2000 records. After filtering, this can reduce the size to around 400.

I'm then using some custom server-side pagination (I'm hitting View State exceptions, so JavaScript isn't an option (I think?)) by taking that List and showing records from contactList[0] through contactList[99], contactList[100] through contactList[199] etc... Below is the method that handles that.

private static List<Contact> GetContactsList(List<Contact> resultsList, Integer pageSize, Integer selectedPage) {
  List<Contact> contactList = new List<Contact>();

  System.debug(LoggingLevel.INFO, '##### In GetContactsList! ' + resultsList.size() + ' @@@ ' + pageSize + ' @@@ ' + selectedPage);

  for (Integer i = (pageSize * selectedPage); contactList.size() < pageSize; i++) {
    contactList.add(resultsList[i]);
    System.debug(LoggingLevel.INFO, '##### ' + resultsList[i] + ' @@@ ' + i);
  }

  System.debug(LoggingLevel.INFO, '##### Finished GetContactsList! Size is: ' + contactList.size());

  return contactList;
}

The variable resultsList is the filtered list of Contacts, pageSize right now is a final variable set to 100 and selectedPage is passed from the Visualforce page to the Controller.

The debug logs show that I have selected page 1 (represented as 0 because, as programmers, we count from 0), the full search size is 2907 records before filtering, 459 after.

Whilst the method is iterating over records, it's finding records in the iteration and displaying information about those records but the list isn't returning anything.

The first 4 pages (records 0 to 400) work fine and a full list of 100 records is shown. However, nothing is displayed for the last page. In this case, it won't show the last 59 records even though it knows they're there.

enter image description here

The page is literally showing a blank list. Even though the for loop is debugging the Contact record and in the very same iterator it's got the .add() method, the final debug statement shows no records added to the list:

enter image description here

No errors or exceptions are being thrown at any point that I can see. Hopefully someone has an idea as I have a feeling I'm overthinking this!

Edit

Finally figured out the problem with thanks to Keith's obvservation. I had to change the method to the following:

private static List<Contact> GetContactsList(List<Contact> resultsList, Integer pageSize, Integer selectedPage) {
  List<Contact> contactList = new List<Contact>();

  Integer start = (pageSize * selectedPage);
  Integer finish = ((resultsList.size() - start) < pageSize) ? resultsList.size() : pageSize + start;

  for (Integer i = start; i < finish; i++) {
    contactList.add(resultsList[i]);
  }

  return contactList;
}

In effect I had to figure out if the starting array, minus the end point was greater or less than 100 (the page size). If it was greater than the page size, just use 100. Otherwise use the end of the size of the List.

I feel like I've probably overcomplicated this and I don't understand why an array out of bounds exception wasn't thrown but still this seemed to be the cause of the problem.

7
  • One problem with the last page is that you logic looks like it will run off the end of the resultList so the loop needs to check for that too i.e. i < resultsList.size() && contactList.size() < pageSize. If you have some try/catch logic in the calling code that might be the cause of the 0 length result.
    – Keith C
    Aug 25, 2017 at 9:46
  • @KeithC that did occur to me after I posted the question. I had tried a try/catch method but suddenly I'm getting Timeout exceptions. Working on something now to address that.
    – Dan Jones
    Aug 25, 2017 at 10:40
  • Best to not use try/catch and get the loop logic right instead.
    – Keith C
    Aug 25, 2017 at 10:53
  • @KeithC I managed to work it out. I'll update my question but as you pointed out, if you write it as an answer I'd be delighted to accept it. I guess the only lingering question I have is, why wasn't an array out of bounds exception thrown because I imagine that's what was happening.
    – Dan Jones
    Aug 25, 2017 at 10:59
  • 1
    Instead of rolling your own pagination, have you considered using StandardSetController? That class provides pagination controls, and can accept a List<SObject>. Seems like that would be the easy way about things here.
    – Derek F
    Aug 25, 2017 at 15:16

1 Answer 1

2

One problem with the last page of results is that your logic looks like it will run off the end of the resultList so the loop needs to check for that too i.e.:

i < resultsList.size() && contactList.size() < pageSize

If you have some try/catch logic in the calling code that might be the cause of the 0 length result if it is hiding the underlying exception and just leaving the results empty.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.