1

I'm using Meteor v0.9.1.1 to populate a small instant message app. This is my chat_box template:

<ul>
  {{#each messages}}
    <li class="msgLine">
      <strong style="color: {{userTextColor userId}}">
        {{userEmail}}
      </strong>
      {{userMsg}}
      <span>{{createdAt}}</span>
    </li>
  {{/each}}
</ul>

What I want to do is that when a user open this template, the last message line will be focused. So I do that by using:

Template.chat_box.rendered = function(){
  var $chat = $(".chatBox"); // get the div contains the messages list
  $chat.scrollTop($chat.height());
};

But it didn't work. Through step-by-step debug, I've found out that the Template.chat_box.rendered function run after the DOM has been initialized, not when all the messages are loaded from the server.

So the question is, how can I know when all the messages have completely loaded into the template, so that after that I can make the $chat.scrollTop($chat.height()); runs correctly.

This is how I get the messages list through publish/subscribe:

Meteor.subscribe('rooms_by_id', this.params._id);
var currentRoomInfo = Rooms.find().fetch()[0];

if (currentRoomInfo) {
  Meteor.subscribe('messages_by_room', this.params._id);
  var _messages = Messages.find().fetch();

  if (_messages) {
    return {
      roomId: currentRoomInfo._id,
      roomTitle: currentRoomInfo.title.toUpperCase(),
      messages: _messages
    }
  }
}
chazsolo
  • 7,873
  • 1
  • 20
  • 44
sonlexqt
  • 6,011
  • 5
  • 42
  • 58

1 Answers1

1

You can use technique which is described here: Meteorjs loading message

However in your case you should make some improvement:

Template.chat_box.rendered = function(){
  Tracker.autorun(function(){
    // every time "chatBoxSubscriptionCompleted" is changed, then closure is rerun
    Session.get("chatBoxSubscriptionCompleted");

    var $chat = $(".chatBox"); 
    $chat.scrollTop($chat.height());
  })
};

Pass onReady callback to Meteor.subscribe :

Meteor.subscribe(
   "chatData",
   param1,param2,
   {
     onReady:function(){
       Session.set("chatBoxSubscriptionCompleted",true)
     },
     onError:function(){}
   }
)

Whenever Session.get("chatBoxSubscriptionCompleted") is changed then closure in Tracker.autorun is being executed.

Community
  • 1
  • 1
Kuba Wyrobek
  • 5,273
  • 1
  • 24
  • 26
  • Is this really the only way of doing this? I would have thought that Meteor would have a better way, e.g. var my_data = Meteor.subscribe('my_collection'); if(my_data){ ...data is loaded so do something...} – JoeTidee Apr 02 '15 at 18:10