Search code examples
mongodbmeteormeteor-publications

What's wrong with my Meteor publication?


I have a publication, essentially what's below:

Meteor.publish('entity-filings', function publishFunction(cik, queryArray, limit) {

  if (!cik || !filingsArray)
    console.error('PUBLICATION PROBLEM');

  var limit = 40;


  var entityFilingsSelector = {};
  if (filingsArray.indexOf('all-entity-filings') > -1)
    entityFilingsSelector = {ct: 'filing',cik: cik};
  else
    entityFilingsSelector = {ct:'filing', cik: cik, formNumber: { $in: filingsArray} };


  return SB.Content.find(entityFilingsSelector, {
    limit: limit
  });


});

I'm having trouble with the filingsArray part. filingsArray is an array of regexes for the Mongo $in query. I can hardcode filingsArray in the publication as [/8-K/], and that returns the correct results. But I can't get the query to work properly when I pass the array from the router. See the debugged contents of the array in the image below. The second and third images are the client/server debug contents indicating same content on both client and server, and also identical to when I hardcode the array in the query.

My question is: what am I missing? Why won't my query work, or what are some likely reasons it isn't working?

enter image description here enter image description here enter image description here


Solution

  • In that first screenshot, that's a string that looks like a regex literal, not an actual RegExp object. So {$in: ["/8-K/"]} will only match literally "/8-K/", which is not the same as {$in: [/8-K/]}.

    Regexes are not EJSON-able objects, so you won't be able to send them over the wire as publish function arguments or method arguments or method return values. I'd recommend sending a string, then inside the publish function, use new RegExp(...) to construct a regex object.

    If you're comfortable adding new methods on the RegExp prototype, you could try making RegExp an EJSON-able type, by putting this in your server and client code:

    RegExp.prototype.toJSONValue = function () {
      return this.source;
    };
    
    RegExp.prototype.typeName = function () {
      return "regex";
    }
    
    EJSON.addType("regex", function (str) {
      return new RegExp(str);
    });
    

    After doing this, you should be able to use regexes as publish function arguments, method arguments and method return values. See this meteorpad.