Reputation: 3065
I am currently working on a chat app in meteor. When first entering the room you get 25 messages initially. Now as new messages come into the page, that value should go up accordingly.
Now I so far I have a tried a couple different things, all not giving the desired result.
I have tried setting up a session variable on the client side that reactively re-subscribes to a given publish as the message count goes up. The problem with this route is this gives an adverse effect as new messages come in where all of the messages on the page need to reload because of the subscribe.
I have recently tried using the reactive-publish
package with little luck in that the package has some various adverse effects of it's own.
What might be the best way to tackle this kind of problem? I am hoping there is a solution where I can set up some kind of publish that just streams in messages based on a numerical value that I in the database for each user.
EDIT: To add context
I am thinking something along the lines of
Meteor.publish 'messages', (roomId) ->
dl = // Some value that I pull from the database, which gets updated as new messages come into a room
Messages.find({room: roomId, type: "user_message"}, {sort: {time: -1}, limit: dl, fields: {_id: 1, name: 1, message: 1, room: 1, time: 1, type: 1}})
Upvotes: 0
Views: 170
Reputation: 2452
It seems like you want each user to have a unique subscription based on the time that they enter the chat room, i.e. Meteor.subscribe("messages", roomId, new Date)
, that includes up to 25 messages from before they entered the room. Here's one option:
Meteor.publish("messages", function (roomId, time) {
var lastRecent = _.last(Messages.find({
room: roomId, type: "user_message"
}, {sort: {time: -1}, limit: 25}).fetch());
var cutoffTime = lastRecent && lastRecent.time || time;
return Messages.find({
room: roomId, type: "user_message", time: {$gt: cutoffTime}
});
});
If you want to successively add e.g. 25 old messages at a time whenever a user scrolls to the top of the chat window, consider that you may not actually need to "subscribe" to those older messages. You may be able to set up a method call like Meteor.call("getNOlderMessages", {roomId: roomId, N: 25, priorTo: oldestShownTime})
to fetch them, insert them into a local collection on the client (e.g. OlderMessages = new Meteor.Collection(null);
), and then do something like:
<template="messages">
{{#each olderMessages}} {{> message}} {{/each}}
{{#each messages}} {{> message}} {{/each}}
</template>
Upvotes: 0
Reputation: 8013
A huge amount of flexibility in Pub/Sub flexibility is achievable by using the low-level publications API - so much so that I've just written a blog post about it. It should make it pretty clear how you update variables when new documents appear in a query set.
Upvotes: 1