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.
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:
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.
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.StandardSetController
? That class provides pagination controls, and can accept aList<SObject>
. Seems like that would be the easy way about things here.