ObserveChanges on client-side cursor


#1

Is there a way to properly add observeChanges call backs to a client-side cursor ? I am returning a set of documents via my helper this way:

Client-side helper:

messages: function(){
var msg = MessengerMsg.find({chatId: Router.current().params._id}, {sort: {‘createdAt’: 1}});
console.log(msg.count());
msg.observeChanges({
added: function(id, fields){
if(fields.new){
console.log(‘added’);
}
}
});
if(msg){
return msg;
}

}

Publish:

Meteor.publish(‘messengerMsg’, function(val, limit){
var initializing = true,
self = this;

Counts.publish(this, 'totalAvailableMessages', MessengerMsg.find({chatId: val.chat}),
        {noReady: true, nonReactive: true});
var data = MessengerMsg.find({chatId: val.chat}, {sort: {'createdAt': -1}, limit: (limit)})
    .observeChanges({
        added: function (id, fields) {
            if(!initializing){
                fields.new = true;
            }
            self.added("MessengerMsg", id, fields);
        },
        removed: function (id) {
            console.log('removed:  '+ id);
        }
});
initializing = false;
self.onStop(function () {
    data.stop();
});
return self.ready();

});

Am I missing something? I am doing per page limits on infinite scrolling and I am trying to increase the limit with each document that is added to the collection without unnecessary re-rendering or re-subscribing of existing items and having to do roundtrips client-server-client-server. I have tried doing it numerous ways, this seems to be working, but I am unable to count new added items as client-side callbacks fire twice for each item. I don’t want to count whole collection via publish-counts every time a new item appears either due to performance issues.

Is there a proper way of doing that?


#2

Mmmm basically your problem is that the above documents are removed and then added back to the client?
and yes there is a much better way to do it (packages) to create a much more beautiful code


#3

why u would need count on client side after every new document?
I would need it only when going for “show more” - that means just once.
Without the whole observeChanges stuff.


#4

I have been using .count() on client side to debug.
@cottz
I am subscribing to a collection let’s say with a limit of 20 of newest (by date) documents. Each additional load runs subscription with increased limit by 20 each time. That works fine.

The problem arises when a new document was added to the collection. If I have 20 documents loaded, just added document is pushed into the collection and the oldest in current collection is removed because Publish allows for a limit of 20 only. I am trying to increase the limit when a new item is added. If I re-subscribe every time new message appears then the subscription re-creates itself unnecessarily on every message as shown below:

["{“msg”:“sub”,“id”:“32HLEAcPobKcQLMzt”,“name”:“messengerMsg”,“params”:…
["{“msg”:“unsub”,“id”:“A5xNGjzhru9tWdcek”}"]

That seems like way too much server side work when new messages will be added since it’s a messenger chat feature.
If my limit is 20 and a new message is added, I am looking to:

  • Keep the 20 documents intact, and just add the new ones to the collection (Done, but can’t sync it properly on next steps)

  • Keep track of the count of new appended documents, let’s say 6 documents

  • Add +6 to the limit next time user tries to load another page of documents via subscribe (current 20 + another page 20 + 6 that were appended)


#5

a solution (which is a bit complex) is use instead of the observer on the server sends the normal cursor and uses an observer in the client about the collection that receives the documents, then copy the new documents in a local collection and ignore remove messages


#6

@cottz I did try that, but for some reason the observer on the client fires callbacks twice for each new document not really sure why. The documents also pile up, meaning that they are looped over in a ‘added’ callback every time new document is added. The callbacks fire in this fashion:
First added document

Document 1 (single new)
Document 1 (all added documents outside the limit)

2nd added document

Document 2
Document 1, Document 2

3rd added

Document 3
Document 1, Document 2, Document 3

And so on. This prevents me from being able to keep track of the number of new documents on the client side outside the limit. This renders me unable to add the new messages to be reflected in the limit for next document page loads. The messages Of course I could create an array of unique IDs, and loop over on every new message, but is that really necessary ? Sounds really taxing and I can’t think of any other way.


#7

I have dropped my observeChanges callbacks all together, just left the prevent remove one to keep the new documents in a client collection. I am subtracting the current limit from client document count and adding it to the next page load limit. I guess it will have to do for now.