0

This is my publish.js file in which I publish my collection:

const tags = Tags.find({title: {
      $regex: `.*${searchString}.*`,
      $options: 'i'
    }}, {
      sort: { counts: -1 }, limit: 3
    });
    console.log(tags.count());

    return tags;

And this is my components which is subscribing to this collection:

this.tagsSubscription = this.subscribe('tags', () => [this.tag], function (err) {
    that.tags = Tags.find().fetch();
});

So with this I get 2 different errors:

  • sort and limit are not working: I sometimes get more than 3 results and there are not sorted by 'counts'

  • the callback is not working properly. It's too fast, I get different result on client and server. I tried with this way, onSuccess() and with Meteor.autorun() but with no luck. If I use a setTimeout I can see the correct cursor

The title search is the only thing that seems working.

Dani
  • 3,128
  • 2
  • 43
  • 91

1 Answers1

2

First, according to documentation, .count() will ignore effects of .skip() and .limit(), so, for example, if you have 100 records in total, and your query options has { limit: 3 } then .count() for this cursor will return 100 instead of 3.

Second, looking at your code I assume that your publication expects at least one argument: searchString. But your code that subscribes to it doesn't pass it. I think it should be like that:

Meteor.subscribe('tags', this.tag, () => {
  that.tags = Tags.find().fetch();
});

And lastly, server-side sorting does not affect documents sorting in client-side collections.

For example, let's assume that you have find query as { num: { $gte: 1 } } and there are 3 documents which satisfy this condition, with nums equal 3, 2 and 1 accordingly. These 3 documents will be sent to client collection from this publication.

Now, let's add new document to this mongo collection, with num: 2.5. What will happen, considering you have { limit: 3 } as query options? The publication will send to client: removed event for document with num: 1 and added event for document with num: 2.5. And client-side collection will have documents in that order: 3, 2, 2.5.

Following this, it should be understandable that you should sort your documents on client side as well. So, in my code above it should be:

that.tags = Tags.find({}, { sort: { counts: -1 } }).fetch();

Also, have a look at documentation regarding what happens when publication arguments are changed.

Styx
  • 9,863
  • 8
  • 43
  • 53
  • 1- Interesting, thanks for clarifying. I see the correct output on the server now BUT if I send an empty string the client displays 4 results (the server just 3). Maybe related with callback issue? 2- Yes, as commented above that works. I send "this.tag" which is a string (searchString on server). I tried yours anyway but I get this error: "Error: argument 2 must be a function" (but don't worry about this) 3- Wow, I copied this info from angular-meteor documentation :S Sorting now on the client but doesn't work. This is not a big deal anyway because I can sort it with AngularJS – Dani Aug 30 '17 at 12:24
  • I don't really understand this: "This is one very important reason why you should always fetch the same data that you have subscribed to (don’t “over-fetch”)." What means with "the same data". Is not always the same? Definitely the problems that I've got with the size of the cursor on the client is related with this. I'll give it a workaround – Dani Aug 30 '17 at 12:27
  • I suspect your client-side collection doesn't get cleared when you re-subscribing with different arguments, so you can add filtering to client side as well, along with sorting/limiting. This way it should work with no issues. – Styx Aug 30 '17 at 12:52
  • Nothing... couldn't find anything related with that issue there. I'm using the subscription/publishing on a proper way. I'm not the only one with that issue btw: https://github.com/Urigo/angular-meteor/issues/1161 I'll try the helper way... – Dani Aug 30 '17 at 14:11
  • 1
    Great! I fixed using a helper. Quite easily btw: tagsSubscribed() { that.tags = Tags.find({}, { sort: { counts: -1 } }).fetch(); }, Thanks for your help bud! – Dani Aug 30 '17 at 21:21