Doctrine - get the offset of an object in a collection (implementing an infinite scroll)
- by dan
I am using Doctrine and trying to implement an infinite scroll on a collection of notes displayed on the user's browser.
The application is very dynamic, therefore when the user submits a new note, the note is added to the top of the collection straightaway, besides being sent (and stored) to the server.
Which is why I can't use a traditional pagination method, where you just send the page number to the server and the server will figure out the offset and the number of results from that.
To give you an example of what I mean, imagine there are 20 notes displayed, then the user adds 2 more notes, therefore there are 22 notes displayed. If I simply requests "page 2", the first 2 items of that page will be the last two items of the page currently displayed to the user.
Which is why I am after a more sophisticated method, which is the one I am about to explain.
Please consider the following code, which is part of the server code serving an AJAX request for more notes:
// $lastNoteDisplayedId is coming from the AJAX request
$lastNoteDisplayed = $repository->findBy($lastNoteDisplayedId);
$allNotes = $repository->findBy($filter, array('createdAt' => 'desc'));
$offset = getLastNoteDisplayedOffset($allNotes, $lastNoteDisplayedId);
// retrieve the page to send back so that it can be appended to the listing
$notesPerPage = 30
$notes = $repository->findBy(
array(),
array('createdAt' => 'desc'),
$notesPerPage,
$offset
);
$response = json_encode($notes);
return $response;
Basically I would need to write the method getLastNoteDisplayedOffset, that given the whole set of notes and one particoular note, it can give me its offset, so that I can use it for the pagination of the previous Doctrine statement.
I know probably a possible implementation would be:
getLastNoteDisplayedOffset($allNotes, $lastNoteDisplayedId) {
$i = 0;
foreach ($allNotes as $note) {
if ($note->getId() === $lastNoteDisplayedId->getId()) {
break;
}
$i++;
}
return $i;
}
I would prefer not to loop through all notes because performance is an important factor.
I was wondering if Doctrine has got a method itself or if you can suggest a different approach.