user2671688
user2671688

Reputation: 691

How can I use collection.find as a result of a meteor method?

I'm trying to follow the "Use the return value of a Meteor method in a template helper" pattern outlined here, except with collections.

Essentially, I've got something like this going:

(server side)

Meteor.methods({
    queryTest: function(selector) {
        console.log("In server meteor method...");
        return MyCollection.find(selector);
    }
});

(client side)

Meteor.call('queryTest', {}, function(error, results) {
    console.log("in queryTest client callback...");

    queryResult = [];
    results.forEach(function(result) {
        // massage it into something more useful for display
        // and append it to queryResult...
    });

    Session.set("query-result", queryResult);
});

Template.query_test_template.helpers({
    query_test_result: function() {
        return Session.get("query-result");
    }
});

The problem is, my callback (from Meteor.call) doesn't even get invoked.

If I replace the Method with just 'return "foo"' then the callback does get called. Also, if I add a ".fetch()" to the find, it also displays fine (but is no longer reactive, which breaks everything else).

What gives? Why is the callback not being invoked? I feel like I'm really close and just need the right incantation...

If it at all matters: I was doing all the queries on the client side just fine, but want to experiment with the likes of _ensureIndex and do full text searches, which from what I can tell, are basically only available through server-side method calls (and not in mini-mongo on the client).


EDIT

Ok, so I migrated things publish/subscribe, and overall they're working, but when I try to make it so a session value is the selector, it's not working right. Might be a matter of where I put the "subscribe".

So, I have a publish that takes a parameter "selector" (the intent is to pass in mongo selectors).

On the client, I have subscribe like:

Meteor.subscribe('my-collection-query', Session.get("my-collection-query-filter"));

But it has spotty behaviour. On one article, it recommended putting these on Templates.body.onCreate. That works, but doesn't result in something reactive (i.e. when I change that session value on the console, it doesn't change the displayed value).

So, if I follow the advice on another article, it puts the subscribe right in the relevant helper function of the template that calls on that collection. That works great, but if I have MULTIPLE templates calling into that collection, I have to add the subscribe to every single one of them for it to work.

Neither of these seems like the right thing. I think of "subscribing" as "laying down the pipes and just leaving them there to work", but that may be wrong.

I'll keep reading into the docs. Maybe somewhere, the scope of a subscription is properly explained.

Upvotes: 4

Views: 1845

Answers (1)

Areca
Areca

Reputation: 1292

You need to publish your data and subscribe to it in your client. If you did not remove "autopublish" yet, all what you have will automatically be published. So when you query a collection on client (in a helper method for example), you would get results. This package is useful just for quick development and prototyping, but in a real application it should be removed. You should publish your data according to your app's needs and use cases. (Not all users have to see all data in all use cases)

Upvotes: 1

Related Questions