0

I'm looking for the best approach to achieve following task with MeteorJS.

Requirements are as follows: list with items, and side bar with selected item (not necessary from current page of the list).

enter image description here

I need to send two pieces of the same Items collection to the client:

  • items for current page of the list
  • one item for the side bar

What dance with publications/subscriptions should I perform?

This is not obvious to me how to do this correctly.

Currently I've added two publications for the list and selected item, subscribed to both of them on the client side. And as a result when I do Items.find() on the client to fill the list, it returns me list page items + selected item ("Item 5" appears on the first page).

It is OK when selected item should be on current page of the list ("Item 2"), but it is NOT OK when selected item should not be there and it's added to the current page anyway ("Item 5").

artin
  • 1,764
  • 1
  • 17
  • 23
  • I would also use two pub/sub. The first would be to list your items. You then want to store the selected item's ids in an array, You can use `Session.get` and `Session.set` to store this. Your second pub would take in one arg which would be that array. And would return all docs where ids are inside that array. – Kassym Dorsel Aug 21 '15 at 12:56
  • @KassymDorsel Yep, but if you have pubs from the same collection, when you do Items.find() on client side you receive _merge_ of items from both pubs... right? That is what I'm facing. List contains item that should not be there. – artin Aug 21 '15 at 13:08
  • Would it be helpful to understand my issue if I add pieces of code? – artin Aug 21 '15 at 16:41
  • Yes, all data from a collection will get merged in the client. This is where using different subs comes in. Even though all items are in the client minimongo, the subscribers control what gets sent to the views to be displayed. You could technically have one pub that supports two subs. I may have time tonight to put an example together. Take a look at this post, it may help: http://stackoverflow.com/questions/19826804/understanding-meteor-publish-subscribe/21853298#21853298 – Kassym Dorsel Aug 24 '15 at 13:58
  • @KassymDorsel That post pretty much explains what I figured out imperatively. Namely _union_ of documents, and need to _duplicate_ find() query on client. One item I still can't get, (that's what Michel proposed) - how same query is going to work properly with skip/limit based paging? When I switch to second page and do Items.find().fetch() in client console, I got items from second page only. Now, if I do the same _skip_ as on server, it will just hide all item on second page. There's no aggregation of items from first and second pages on client either... – artin Aug 24 '15 at 17:44
  • I don't know how you do your pagination, but probably with `skip()` and `limit()`. Either of these and `fetch()` change the state of your cursor (By iterating over it). That's why you only get items from the second page. You'll need to `rewind()` the cursor first. – Kassym Dorsel Aug 24 '15 at 18:18

1 Answers1

0

Your approach to use two publications and two subscriptions is correct. The consequence is that the collection on the client will contain the union of the data from the two pubsubs. Given that the two publications perform different queries, you need your two views on the client to execute those same queries on the local collection. As @KassymDorsel says, Session variables or reactive variables may be useful for managing state.

Michel Floyd
  • 18,793
  • 4
  • 24
  • 39
  • I've tried same queries for the list, it broke my paging. Why would it help? Server pub skip/limit frame of items and send to client. Client skip/limit similarly, but on the frame received from server. Obviously I have no items with same query starting from second page... – artin Aug 21 '15 at 16:36
  • A pubsub *adds* documents to the client-side minimongo database. A *query* in a template helper selects a subset of those documents from the client-side minimongo database to use in the UI. – Michel Floyd Aug 21 '15 at 17:37
  • Hmm.. Interesting. If it would _add_ documents it would probably work when I go from fist page and click second and further. Items would aggregate in minimongo and same query skip/limit frame properly. But what if I get current page from url? What if I go first page then third? Minimongo db will not replicate exact server collection state, right? If it would _add_. But I do not see _adding_: open first page, go to the console, Items.find().fetch() == items from first page. Go to the second page, Items.find().fetch() == items from second page. No union of pages in local db. Any idea? – artin Aug 21 '15 at 18:03
  • Minimongo *will* replicate server state. Are you using a pagination package? There are several popular ones on atmospherejs. If the sidebar item is always just one then it can be retrieved with a *findOne()* instead of a *find()* – Michel Floyd Aug 21 '15 at 18:35
  • Only package I use for paging is "tmeasday:publish-counts", because publishing total items count is surprisingly not obvious task in Meteor. I already use Items.findOne() for selected item. – artin Aug 21 '15 at 19:02