eawer
eawer

Reputation: 1448

How to perform Meteor.call on Session variable change

Here is what I have:

Templates:

<body>
  {{> resultSession}}
  {{> resultMethod}}
</body>

<template name="resultSession">
  <button>Click me</button>
  <p>Session.get('length') returned {{returned}}</p>
</template>

<template name="resultMethod">
  <p>Meteor.call returned {{returned}}</p>
</template>

Client-side:

Template.resultSession.events({
  'click button': function () {
    Session.set('length', Math.floor((Math.random() * 20) + 1));
  }
});

Template.resultSession.helpers({
  returned: function () {
    return Session.get('length');
  }
});

Template.resultMethod.helpers({
  returned: function() {
    Meteor.call('returnArray', Session.get('length'), function (err, res) {
      return res.length;
    });
  }
});

Server-side:

Meteor.methods({
  'returnArray': function (length) {
    var arr = [];
    arr[length - 1] = 0;
    return arr;
  }
});

TL;DR

You can look at code and play with it here http://meteorpad.com/pad/AkBZq4ZFjJuQuzztz/Meteor.call-on-Session-change

As you can see, my method accepts number and returns the array with length equal to number.

The question is how can I make Meteor.call fire each time Session variable changes?

P.S. Values are returned to two different templates on purpose

Upvotes: 0

Views: 2107

Answers (3)

mwarren
mwarren

Reputation: 2469

Your reactive code is working perfectly. If you put a console.log in the Meteor.call you will see that the correct answer is coming back from the server.

Template.resultMethod.helpers({
  returned: function() {
    Meteor.call('returnArray', Session.get('length'), function (err, res) {
      console.log('it came back ' + res.length);
      return res.length;
    });
  }
});

I have put a Session variable into the return from the server, so now you can see that your reactive code works very simply - no need for complicated autorun stuff.

<template name="resultMethod">
  <p>Meteor.call returned {{returned}}</p>
</template>

Then in the resultMethod helper:

Template.resultMethod.helpers({
  returned: function() {
    Meteor.call('returnArray', Session.get('length'), function (err, res) {
      Session.set('fromServer', res.length + '');
    });
    return Session.get('fromServer');
  }
});

Upvotes: 2

Carlos Rodrigues
Carlos Rodrigues

Reputation: 160

Like @saimeunt said, use Tracker.autorun

Templates:

<body>
  {{> resultSession}}
  {{> resultMethod}}
</body>

<template name="resultSession">
  <button>Click me</button>
  <p>Session.get('length') returned {{returned}}</p>
</template>

<template name="resultMethod">
  <p>Meteor.call returned {{returned}}</p>
</template>

And code:

Template.resultMethod.rendered = function() {
    this.autorun(function (){
        Meteor.call('returnArray', Session.get('length'), function (err, res) {
            Session.set('result', res);
        });
    });
}

Template.resultSession.helpers({
  returned: function () {
    return Session.get('length');
  }
});

Template.resultMethod.helpers({
  returned: function() {
    return Session.get('result');
  }
});

Autorun inside rendered stops when the template is not rendered

Upvotes: 1

saimeunt
saimeunt

Reputation: 22696

You could simply refactor your code to call the Meteor method on click event ?

Template.resultSession.events({
  'click button': function () {
    var length = Math.floor((Math.random() * 20) + 1);
    Session.set('length', length);
    Meteor.call('returnArray', length, function (err, res) {
      Session.set('result', res.length);
    });
  }
});

Template.resultSession.helpers({
  returned: function () {
    return Session.get('length');
  }
});

Template.resultMethod.helpers({
  returned: function() {
    return Session.get('result');
  }
});

You could also use Tracker.autorun to track modifications of your Session variable and rerun arbitrary code.

Tracker.autorun(function(){
  var length = Session.get("length");
  console.log("length new value =", length);
});

Upvotes: 0

Related Questions