Search code examples
javascriptpaginationkeystonejslocals

Can't implement KeystoneJS Pagination concurrently


I'm trying to implement pagination in keystone js andf I'm doing it as follows:

Model

var keystone = require('keystone');
var Types = keystone.Field.Types;

var Test = new keystone.List('Test', {
    map: {name: 'title'},
    label: 'Test',
    singular: 'Test',
    plural: 'Tests',
    autokey: {path: 'slug', from: 'title', unique: true} 
});

Test.add({
    description: {type: Types.Html, wysiwyg: true, height: 300 }
});

Test.register();

Route / View

var keystone = require('keystone');
var Test = keystone.list('Test');
exports = module.exports = function(req, res) {

    var view = new keystone.View(req, res);
    var locals = res.locals;

    // Set locals
    locals.section = 'test';
    locals.data = {
        test: []
    };


    Test.paginate({
        page: req.query.page || 1,
        perPage: 2,
        maxPages: 5
    })
    .exec(function(err, results) {
        locals.data.test = results;
        next(err);
    });

    // Load All Terms
    view.query('test', keystone.list('Test').model.find()); 

    // Render view
    view.render('test');
}

In Index.js

app.all('/test', routes.views.test);

In middleware.js

res.locals.navLinksFooter = [
    { label: 'Test', key: 'test', href: '/test' },
    .....
];

Template

 <div class="row">
    <div class="col-xs-12">
        <span class="pull-right">
            {{>pagination}}
        </span>
    </div>
</div>

<div class="row row-content panel--outer panel--outer--trans">
    <div class="col-xs-12" id="panel--news-detail">
        {{# each test}}
            <p>{{{description}}}</p>
        {{/each}}
    </div>
</div>

Unfortunately, when I try to go to the page I get the following error:

"ReferenceError: next is not defined"

Some pointers and possible causes. I've already set up pagination for blog posts on a separate page using:

locals.data = {
    test: []
};

If I comment out "next(err)", the pagination buttons appear but clickiong on the arrow takes me to the second page of blog/news items.

Things are obviously getting mixed up somewhere here. I suspect it's due to my mishandling of locals but I can't seem to find any in depth explanation on the keystone site of how locals are supposed to work.

I ultimately want to apply different filters to the mongo collection and have it running in a series of bootstrap tabs but I think I need to get the basics sorted out first.

Has anyone been faced with a similar situation and been able to find the solution?


Solution

  • next is a callback function that runs within your Express route. You don't have it defined as an argument in your route at all; part of the problem is also that you are trying to load the data synchronously, which doesn't work here.

    Use the view.init function to expose the next function, then call it when you've loaded information from your database into locals.data.

    route/view

    var keystone = require('keystone');
    var Test = keystone.list('Test');
    exports = module.exports = function(req, res) {
    
        var view = new keystone.View(req, res);
        var locals = res.locals;
    
        // Set locals
        locals.section = 'test';
        locals.data = {
            test: []
        };
    
    
        view.on('init', function (next) {
            Test.paginate({
                page: req.query.page || 1,
                perPage: 2,
                maxPages: 5
            })
            .exec(function(err, results) {
                locals.data.test = results;
                next(err);
            });
        });
    
        // Load All Terms
        view.query('test', keystone.list('Test').model.find()); 
    
        // Render view
        view.render('test');
    }