Exception from sub search id NqQgYv3aYgoqcqqJp undefined


#1

I have a publish on the server:

if (Meteor.isServer) {
  Meteor.publish("search", function (query) {
    var re = new RegExp(query, "i");
    var chartsFound = Chart.find({"demographics.lastName": {$regex: re}}, {limit: 500, sort: {"demographics.lastName": 1}});
    return chartsFound;
  });

and then a template helper on the client:

 Template.searchResults.helpers({
    theCharts: function () {
      var re = new RegExp(Session.get('searchString'), "i");
      var chartsFound = Chart.find({"demographics.lastName": {$regex: re}}, {limit: 500, sort: {"demographics.lastName": 1}});
      return chartsFound;
    }
  });

And a search form that takes the search term and sets the session variable and subscribes to that search term:

Template.navbar.events = {
    'submit #searchForm': function (e) {
      e.preventDefault();
      Router.go('/search');
      var searchString = e.target.liveSearch.value;
      Session.setPersistent('searchString', searchString);
      searchSubsManager.clear();
      searchSubsManager.subscribe("search", searchString);
    }
  }

and this works well … I change the session variable “searchString” and the search refreshes. What I would like to do now is what I believe I read somewhere as a suggested practice, and that is to move the “Find” logic into a meteor.method, because as you can see, I have the same logic coded twice:

Chart.find({"demographics.lastName": {$regex: re}}, {limit: 500, sort: {"demographics.lastName": 1}});

so, here is the method I tried to define:

Meteor.methods({
  findChartsByLastName: function (lastName) {
    var re = new RegExp(lastName, "i");
    var chartsFound = Chart.find({"demographics.lastName": {$regex: re}}, {limit: 500, sort: {"demographics.lastName": 1}});
    return chartsFound;
  }
});

and then I tried to call it from the publish:

Meteor.publish("search", function (query) {
    var chartsFound = Meteor.call('findChartsByLastName', query);
    return chartsFound;
  });

But, when I did this I got the error “Exception from sub search id…”

Any help would be greatly appreciated! thank you.


#2

Your first method looked correct. The publish logic belongs in Meteor.publish. You would use Meteor.methods to perform actions on your collections.


#3

I’m sorry but I don’t understand what you are saying… ?


#4

The way you were doing it before is the correct way. To make it reactive you could do something like this:

// isClient
Tracker.autorun(function () {
    Meteor.subscribe('search', Session.get('searchString'));
});

Then in your helper you only need:

 Template.searchResults.helpers({
    theCharts: function () {
      return chartsFound = Chart.find({});
    }
  });

#5

Making it reactive is not the problem… the problem I’m having is that I’m trying to find a way to not have this code:

var re = new RegExp(lastName, "i");
var chartsFound = Chart.find({"demographics.lastName": {$regex: re}}, {limit: 500, sort: {"demographics.lastName": 1}});

in 2 places (once in the publish, and once on the client in order to “re-find” the correct results.

I think I saw some post about a suggested way to do this by having a method that is called from both the publish method and the client, however, when I try to declare a method I get the error:

Exception from sub search id ..... undefined

#6

How are you subscribing for the Chart collection? Do you have only 1 subscription or multiple?


#7

Every time the user clicks the search button, I take what they typed and subscribe to the search publish with that query string, but first I clear the previous “search” subscription so I don’t have a lot of search results building up on the client. I also have Chart documents coming back to the client as part of a different publish on the server (charts of a certain status, unrelated to the current search query), so I definitely need to “refind” the correct documents on the client.


#8

Do you have autopublish package installed?


#9

no, I removed it when I started doing publish subscribe. I have 50,000 documents in the collection, so I don’t want them all on the client :smile:


#10

Does not hellstad’s solution achieve what you want? Going that way, the only documents the client is subscribed to are the ones they searched for. Thus you don’t need the long query in both places. As you can see, the helper simply returns the entire client side collection as it only contains what they searched for.


#11

He has another subscription for the Chart collection it looks like, so my solution would return those too. He still needs the query params for the collection.find() on the client. I would just separate my subscriptions using routes.


#12

Correct, I have multiple subscriptions, all pulling up the same document types, so they are all bundled together… so, I’m trying to avoid the duplicate code by putting the Collection.find call into a method, but as my post explains, I got a strange error when I did this. Searching up that error didn’t lead me anywhere, since it’s so unique to me… I’m hoping someone here can help debug that error, and/or show me the proper way to move my common code into a method that can be shared.


#13

How do you define the method? Is it supposed to run on the server or client? If the method is defined on both client and server (stub method), are you checking for isSimulation to distinguish client vs. server?


#14

I defined it outside the isClient and isServer conditionals, to make it available in both places… I thought I read this somewhere as a good practice. I’m doing this same thing for my methods that insert and delete documents, so it runs the code on both client and server.

Why would I need to distinguish client vs server in this situation?


#15

Because the client only has access to collections in minimongo, whereas the server has access to the entire collection. So if you call a method and try to access a particular document which might not have synced to the client, then the client stub method and the server method with have different outcomes.


#16

ok, I understand that. In my particular situation, I’m doing a find in a publish on the server, then finding those same documents again on the client. I think this is the recommended pattern when you have more documents in your mongo db than you want on the client at any one time. So, my question remains… how do I debug the error message I’m getting when I define a method as I have, and try to call it in my publish? (my last 2 code samples in my original post)