Doctrine - get the offset of an object in a collection (implementing an infinite scroll)

Posted by dan on Stack Overflow See other posts from Stack Overflow or by dan
Published on 2012-05-30T17:17:27Z Indexed on 2012/06/11 10:40 UTC
Read the original article Hit count: 219

Filed under:
|
|
|

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.

© Stack Overflow or respective owner

Related posts about php

Related posts about doctrine