Mikeyy
Mikeyy

Reputation: 13

Pagination with appengine ndb Cursor - python : Same cursor is being generated leading to repeatition of output results

I realised from my appengine log that the same cursor is being generated each time, the call to the Homehandler is made. Please any idea what i am doing wrong, below is a snippet of my code:

class HomeHandler(webapp2.RequestHandler):
def get(self):
    #page=self.request.get("page", default_value="1");
    q = Allnews.query().order(-Allnews.date_added)
    cursor = ndb.Cursor(urlsafe=self.request.get('cursor',default_value=None))
    items, next_curs, more = q.fetch_page(30, start_cursor=cursor)
    if more:
        next_c = next_curs.urlsafe()
    else:
        next_c = None
    context = { "news":items,"cursor":next_c}
    # context["headlines"]=Feed.query(Feed.feed_cat.title == 'Headlines')
    # context["gossip"] = Feed.query(Feed.feed_cat.title == 'Gossip')
    # context["sports"] = Feed.query(Feed.feed_cat.title == 'Sports')
    self.response.out.write(template.render('templates/homefeed.html',context))  

this is the section of my homefeed.html template, I m using 'infinite scrolling' technique to fetch more results

<script>
{% if cursor %}
$(window).scroll(function()
{
var src=$("#src_val").val();
if($(window).scrollTop() == $(document).height() - $(window).height())
{
    $('div#loadmoreajaxloader').show();
    $.ajax({
    url:"/home",
    type:'GET',
    data: {cursor: '{{cursor}}',feed_id:src },
    success: function(news)
    {
        if(news)
        {
            $("#wrapper").append(news);
              $('div#loadmoreajaxloader').hide();

        }else
        {
        $('div#loadmoreajaxloader').html('No more posts to show.');
        }
    }
    });
}
});
{% endif %}
</script>

Upvotes: 0

Views: 1780

Answers (1)

Brent Washburne
Brent Washburne

Reputation: 13158

It looks like you're using the get() method for both displaying a page and to handle an AJAX request. It's correctly generating a page with an initial cursor, but your $.ajax() method is expecting it to return JSON data.

Split the page request and AJAX request into two methods. Try adding a post() method to your HomeHandler that returns JSON data like this:

import json

def post(self):
    q = Allnews.query().order(-Allnews.date_added)
    cursor = ndb.Cursor(urlsafe=self.request.get('cursor',default_value=None))
    items, next_curs, more = q.fetch_page(30, start_cursor=cursor)
    if more:
        next_c = next_curs.urlsafe()
    else:
        next_c = None
    self.response.headers['Content-Type'] = 'application/json'   
    self.response.out.write(json.dumps({'news': items, 'cursor': next_c))

Now you have a method that returns JSON data to the AJAX request:

<script>
var cursor = null;
$(window).scroll(function()
{
if($(window).scrollTop() == $(document).height() - $(window).height())
{
    $.ajax({
    url:"/home",
    type:'POST',
    data: {cursor: cursor},
    success: function(data)
    {
        $("#wrapper").append(data['news']);
        cursor = data['cursor'];
        if ( !cursor )
            $('div#loadmoreajaxloader').show().html('No more posts to show.');
    }
    });
}
});
</script>

Notice how the cursor value is updated on each AJAX request. This is how you will get a new cursor on the next request.

(This code was not tested, you may need to debug it.)

Upvotes: 1

Related Questions