Search code examples
meteorbackbone-eventseventtrigger

Converting from Backbone habits to Meteor: trigger events


In Backbone, if you want to talk between models you usually do it throug events. For example, if sayHi() should be done in a Friend model rather than in a Stranger model, you'd do the following.

inside Stranger

Friend.trigger("callSayHi");

inside Friend

this.listenTo("callSayHi", function() {
  sayHi();
}

I wanted to do the same in Meteor and I thought using a Session var fitted.

inside Stranger

Session.set("callSayHi", true);

inside Friend

if (Session.get("callSayHi") {
  sayHi();
}
// Session.set("callSayHi", false); <-- PROBLEM

Let's leave out the problem of scoping (using a ReactiveVar is better, etc.) here. The problem is, to handle this situation more appropriately, I would have to set the session var at the end to false again but that would invoke sayHi() event infinitely. I feel like this kind of situation is very common. What's the Meteor way of handling it?

Might be related: https://forums.meteor.com/t/track-template-state-the-template-instance-scoped-reactive-way-instead-of-using-session-vars/3048


Solution

  • You can use a tracker, either inside or outside a template. It will rerun as soon as one of its reactive dependency change.

    Example outside of a template:

    Tracker.autorun(function() {
      //will be run only once when Session.get('callSayHi') is true
      if(Session.get('callSayHi') {//dependency on Session var
        sayHi();
        Session.set("callSayHi", false);
      }
    });
    

    Example inside a template:

    Template.yourTemplate.onCreated(function(){
      this.autorun(function() {
        //will be run only once when Session.get('callSayHi') is true
        if(Session.get('callSayHi') {//dependency on Session var
          sayHi();
          Session.set("callSayHi", false);
        }
      });
    });