Code not behaving as expected, loading messages in a certain room


#1

I’m just trying to build a simple chat application that has various rooms. Each message in my Messages collection has a room property, and obviously only messages matching the current room should be displayed.

First up, the relevant router code (FlowRouter w/ BlazeLayout):

FlowRouter.route('/room/:room', {
		name: 'room',
		action: function(params) {
			Session.set('room', params.room)
			BlazeLayout.render('appLayout', { chatAreaTemplate: 'chatArea'});
		}
	})

pretty self explanatory.

Next, the relevant helpers for the chatArea:

Template.chatArea.onCreated(function() {
    var self = this;
    console.log('DEBUG: right before autorun, room = ' + Session.get('room'))
    self.autorun(function() {
        console.log('DEBUG: autorun called room =' + Session.get('room'))
        self.subscribe('messages', Session.get('room'));
    });
});

Template.chatArea.helpers({
	messages: Messages.find({room: Session.get('room')}),
	'fromCurrentUser': function(user) {
		if (user._id === Meteor.userId()) {
			console.log('true')
			return true;
		} else {
			console.log('false')
			return false;
		}
	}
})

So, whenever I click on a new room, the router kicks in and sets the proper Session variable. When this happens, I know the .autorun() function fires because I can see the console.log() statement being printed. The issue is, I know Meteor is reactive, and I was expecting the messages the chatArea to be reloaded according the currently set room. Instead, nothing is reloaded, so I can click around to a buch of different rooms (routes) and the same messages are displayed.

What am I doing incorrectly here?


#2

Not sure what the exact problem is, but seems like you’re relying on Session vars when you don’t really have to. Flow-Router offers reactivity out of the box, so you could do something like:

FlowRouter.route('/room/:room', {
  name: 'room',
  action: function (params) {
    BlazeLayout.render('appLayout', { chatAreaTemplate: 'chatArea' });
  }
});

Template.chatArea.onCreated(function () {
  var self = this;
  self.autorun(function () {
    self.subscribe('messages', FlowRouter.getParam('room'));
  });
});

Template.chatArea.helpers({
  // You only really need to filter this by the room _id if you have multiple messages subscriptions
  messages: Messages.find({}),
  
  'fromCurrentUser': function (user) {
    if (user._id === Meteor.userId()) {
      return true;
    } else {
      return false;
    }
  }
});

#3

No, this would just display all messages in every room, which is not what i want. If I then filter my .find() call like so:

Template.chatArea.helpers({
  // You only really need to filter this by the room _id if you have multiple messages subscriptions
  messages: Messages.find({room: FlowRouter.getParam('room')}),
  
  'fromCurrentUser': function (user) {
    if (user._id === Meteor.userId()) {
      return true;
    } else {
      return false;
    }
  }
});

nothing at all shows in any room.


#4

You should be controlling which messages are available through the pub/sub. You shouldn’t need to filter at the helper level as well.