Meteor Subscribe doesn't update sort order of collection
Asked Answered
R

2

20
// Snippet from Template
<div class="post-container">
  {{#each elements}}
    {{> post-element this}}
  {{/each}}
</div>

// Snippet from Client 
Meteor.subscribe('thePosts');

// Snippet from Server
Meteor.publish('thePosts', function(){
  return Posts.find({},  {sort:{createdAt:-1}, reactive:true});
});

When I do...

Posts.insert({body:postBody, createdAt: new Date()});

The post document gets added and appears at the end of my list, as opposed to descending order as specified in my publish function. Any idea about what I am doing wrong?

Thanks!

Reverso answered 1/3, 2013 at 8:19 Comment(0)
T
49

The publish function determines which records should be synced to the mini-mongo database of any subscribing clients. So sorting the data in the publish function actually has no effect on the client, as the client-side database will likely store them in some other way.

Of course you may want to use sort in a publisher's find in order to limit the number of records to the N most recent - but again this is just a way of deciding which records get synced and not how they are to be stored/used by the client.

Once the records have been synced to the client, it is up to the template code to determine how the results should be displayed. For example:

Template.myTemplate.elements = function() {
  return Posts.find({}, {sort: {createdAt:-1}});
}

Also see the "sorted publish" section of my post on common mistakes.

Trioxide answered 1/3, 2013 at 17:55 Comment(2)
David, this is really the question I was looking to have answered! Excellent answer, thank you so much!Reverso
These days, one of my favorite type of moments on SO is to have a meteor question, find the David Weldon answer to it, and smile while up-voting it. Cheers David (& ty)Isaak
B
4

You didn't posted your template helper code.

When you do return Posts.find() from the helper function, the query should also contain the sort arguments, like as below:

Template.myTemplate.elements = function(){
   Meteor.subscribe('thePosts');
   return Posts.find({},  {sort:{createdAt:-1}, reactive:true});
}
Blah answered 1/3, 2013 at 13:53 Comment(5)
Template functions run in a reactive context so the reactive:true is not needed.Trioxide
Yeah, I thought it was defaulted to true, I was just messing around with different solutions.Reverso
sohel, you were correct the helper function should be doing filtering. The publish pushes syncs document to browser. I now understand what's going on here thanks guys!Reverso
how about if you want to sort based on geo-location? it's as if that field is not exposed by MongoDB.Ambit
When you sort large amount of data on client side, it hangs the browserSpotted

© 2022 - 2024 — McMap. All rights reserved.