Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

preventing duplicates infinite scrolling ajax loader

it might just be too late at night for me to see a clear solution here, but I figured I'd get some thoughts from anybody with an opinion...

the site i'm working on has a long list of user posts. i've got all the scroll event handlers working to ajax in the next batch of 100 posts when you reach or approach the bottom.

my question is... How do i prevent the following scenario?

  1. UserX visits the site and loads posts 1-100
  2. 10 more users visit the site and add 10 more posts
  3. UserX scrolls to bottom and loads posts 101-200, which used to to be posts 91-190
  4. UserX ends up with duplicates of posts 91-100 on the page

i'll include a stripped down version of my code below in case it helps anybody else along

$.ajax({
    type:'POST',
    url:"/userposts.php",
    data:{ limit: postCount },
    success:function(data) {
        $("postsContainer").append(data);
        if ( $("postsContainer").find("div[id='lastPostReached']") ) {
            // unbind infinite scrolling event handlers
        }
    },
    dataType:'html'
});

in my PHP script I have essentially the following:

if ( ! isset($_POST["limit"]) ) {
    $sql .= " LIMIT 101"; // initial request
} else {
    $sql .= " LIMIT {$_POST["limit"]},101
}

$posts = mysql_query($sql);
while( $post = mysql_fetch_assoc($posts) ) {
    /* output formatted posts */
}

// inform callback handler to disable infinite scrolling
if ( mysql_num_rows($posts) < 101 ) {
    echo '<div id="lastPostReached"></div>';
}

This gives me infinite scrolling nice and easy, but how can I prevent the hypothetical duplicates that would show up when new records have been added to the table between ajax requests?

like image 881
overeasy Avatar asked Jan 05 '12 08:01

overeasy


2 Answers

You define a timestamp from php that indicates the servertime at the time the page loads (eg var _loadTime = <?php echo time(); ?>) and then pass this value as part of the Ajax data config object along with limit.

Then on the server side you can exclude any posts that were created after this time and hense preserve your list.

You can also go a step further and use this time along with a basic ajax long polling technique to notify the user of new posts since the page loaded/last loading of new posts - similar to Facebook and Twitters feeds.

like image 122
nav Avatar answered Sep 22 '22 00:09

nav


Update your ajax request, so that in addition to the limit parameter you pass through the current range of post ids (I'm assuming the posts have some kind of unique id). Update your php to take those parameters into account when retrieving the next set of posts.

That is, instead of saying "give me another 100" the request is "give me 100 starting at id x".

(Sorry, I don't have time now to write an example code for this.)

like image 29
nnnnnn Avatar answered Sep 18 '22 00:09

nnnnnn