Robert W. Hunter
Robert W. Hunter

Reputation: 3003

Meteor strange behaviour

I'm testing some routines that Meteor has and I would like to know if this is it's normal activity or I have something wrong...

I will describe step by step:

I publish my collection in order to have only what I want

server/publish.js

Meteor.publish('decisions', function (decisionCursor) {
    return Decisions.find({ active: true }, { limit: 20, skip: decisionCursor });
});

Meteor.publish('decisionsToModerate', function (decisionCursor) {
    return Decisions.find({ active: false }, { sort: { createdAt: -1 }, limit: 1, skip: decisionCursor });
});

I subscribe my client to both collection publications

client/client.js

Meteor.startup(function () {
    SimpleSchema.debug = true;
    Session.setDefault('decisionCursor', 0);
    Deps.autorun(function () {
        Meteor.subscribe("decisions", Number(Session.get('decisionCursor')));
        Meteor.subscribe("decisionsToModerate", Number(Session.get('decisionCursor')));
    });
});

I set up functions to retrieve both collections in order to prevent calling a query everytime...

client/lib/environment.js

activeDecisions = function() {
    var decisions = Decisions.find({active: true});
    console.log(decisions.fetch().length); // PROBLEM HERE
    return decisions;
};
moderateDecisions = function() {
    return Decisions.find({active: false});
};

I create my view stuff

client/views/home/home.js

Template.home.activeDecisions = function() {
    var decisions = activeDecisions();
    return decisions;
};

As you can see, on client/lib/environment.js I have added a line for you to see where I see the problem...

When I go to http://localhost:3000/ iron-routes loads

this.route('home', {
    path: '/',
    layoutTemplate: 'masterLayout'
});

If I got o Chrome Console, as I wrote on client/lib/environment.js it should return a line with a number of Decisions documents, in this case I only have 3 active Decisions, but Chrome outputs this:

0 environment.js?9868bbbef2024c202fd33213ed060f067dadbe75:3
3 environment.js?9868bbbef2024c202fd33213ed060f067dadbe75:3
3 environment.js?9868bbbef2024c202fd33213ed060f067dadbe75:3

Three lines, first one tells me that I have 0 documents (what? I have THREE active documents) next two lines tells me exactly what I wanted to know, that I have three documents.

I want this number because I want to set it in a session variable that will update every time that query is called because if I set it in other place (let's say for example Template.home.rendered) I will make TWO querys and that will be slower.

So the problem I see is that I don't know why Meteor writes three times into console if I told it to write it only once, when query is parsed to a variable... If I set session it will be 0, then 3 and then 3... That may cause some bugs?

Upvotes: 0

Views: 92

Answers (1)

David Weldon
David Weldon

Reputation: 64342

Template helpers form a reactive context - if reactive variables inside of them get updated, the helper will run again. So whenever the cursor returned by activeDecisions gets updated you will see that line get printed to the console.

It's perfectly reasonable for the function to print 0 when the template is first rendered. Remember that the documents you subscribed to may not have arrived on the client before the template is rendered. As new documents arrive or get updated, activeDecisions will be evaluated again. For more details see my blog post on a similar subject.

Going back to your original question, you can set a session variable to the cursor count (BTW it's more efficient to call cursor.count() than cursor.fetch().length). When that count gets updated, so will your session variable. Because session variables are reactive, all of its dependencies will be rerun again and so on.

Upvotes: 1

Related Questions