5

I'm trying to make a pagination function for use in a Meteor client. Therefore I need to know the record count on the server.

On the server (in server/bootstrap.coffee) I have this code:

Meteor.methods
  ContactsCount: ->
    Contacts.find().count()
    console.log("Totalrecords: " + Contacts.find().count())

The server part is called (it displays the correct number on the console - 40)

On the client I have:

$.extend Template.pager,
  GetRecordCount: ->
    Meteor.call("ContactsCount", (error,result) ->
    console.log('r', result)

From the browser console Template.pager.RecordCount() returns

undefined
r 30

I understand the 'undefined' is the return from Template.pager.RecordCount() and it is returned first.

When the result comes available it is displayed to the console.

But how do I get the value of result in my pager template?

I'm searching java callbacks for a few hours now, but whatever I try, I cant get it to work.
Please help.

Here is an update.

I looked at the documentation for invalidate. But the example doesn't help me much. The temperature is set in the client with a paramater in the function call. So there is no callback used. The callback was my problem.

I solved it like this:

Meteor.call("ContactsCount", myFunc)

### This is the call back function when the server
    function 'Meteor.call("ContactsCount", myFunc)' is called
    When the result from the server call is returned, this will be executed ###
myFunc = (error, result) ->
if !error
    pages = result / Session.get("page_size")
    Session.set "total_pages", Number(pages.toFixed(0) + 1)
    Session.set "total_records", result
if error
    console.log(error)

This works. I'm still wondering if this is the best solution. I have a lot of Session.set() calls and maybe there is too much triggering going on.

### This function will set the css classes
    for enabling or disabling the pager buttons
    in the Pager Template in myapp.html ###
SetPagerButtons = ->
 Meteor.call("ContactsCount", myFunc)
 if Session.get("current_page") <= 1
    Session.set "nextEnabled", ""
    Session.set "lastEnabled", ""
    Session.set "firstEnabled", "disabled"
    Session.set "previousEnabled", "disabled"
    Session.set "last_record", false
 else if Session.get("last_record") or Session.equals("current_page",  Session.get("total_pages"))
    Session.set "nextEnabled", "disabled"
    Session.set "lastEnabled", "disabled"
    Session.set "firstEnabled", ""
    Session.set "previousEnabled", ""
 else
    Session.set "nextEnabled", ""
    Session.set "lastEnabled", ""
    Session.set "firstEnabled", ""
    Session.set "previousEnabled", ""
    Session.set "last_record", false
Eric Roijen
  • 51
  • 1
  • 3

1 Answers1

2

You need to invalidate the template, this can be done by using sessions in your template helper, using collections or using the invalidate context:

http://docs.meteor.com/#invalidate

Update:

To be honest what you have is correct as you say, I would just minimise the number of sessions. Basically there are three ways to invalidate a template: force an invalidation with context.invalidate(), Update a client collection or update a session.

So yeah you could use this code (Sudo messy as I don't use coffee script)

//client server call
total_records = 0
page_numbers_context = null

Meteor.call("ContactsCount", contactsCountCallback)

contactsCountCallback = (error, result) ->
if !error
    total_records = result
    if page_numbers_context
        page_numbers_context.invalidate();
if error
    console.log(error)



//Add template handler
Handlebars.registerHelper('page_numbers', pageNumberCallback);
pageNumberCallback = (options)  ->
    page_numbers 

    var context = Meteor.deps.Context.current;
    if context && !page_numbers_context
        page_numbers_context = context
        context.on_invalidate ->
            page_numbers_context = null

    pages = total_records / page_size
    total_pages = Number(pages.toFixed(0) + 1)
    //HTML code built with ifs here


//In template:
{{#page_numbers}}{{/page_numbers}}
jonathanKingston
  • 1,407
  • 10
  • 16
  • Personally I am doing similar things by calling invalidate on the correct context when the callback is done. You are basically doing the same things but with sessions. I am however using helpers which allow you to return html strings but you could implement it other ways. I will add a code sample to my answer above. – jonathanKingston May 02 '12 at 11:43
  • I would love to see a code sample using invalidate. I have the idea that using Session too much will trigger a lot of internet actions that maybe can be avoided. The full code for my pager example is on github: github.com/eric-naguras/MyApp.git – Eric Roijen May 02 '12 at 12:29
  • Sessions are not server side so there is no worry of increased io there. I will have a look later, code sample is above :) – jonathanKingston May 02 '12 at 12:59