Code Monkey home page Code Monkey logo

meteor-reactive-method's Introduction

Meteor Reactive Methods

Call methods synchronously inside Tracker.autorun.


Deprecated: Please fork this package if you would like to continue to work on it, and I'd happily link to it!


Install with meteor add simple:reactive-method

Sometimes, you want to call a Meteor method inside of a template helper or Tracker.autorun computation, and get a return value. Now you can!

Before (doesn't work)

Template.foo.helpers({
   methodResult: function () {
       Meteor.call("myMethod", "a", "b", function (err, result) {
           return result; // this doesn't work!!!
       });
   } 
});

After (works!)

Template.foo.helpers({
    methodResult: function () {
        // Super fun!
        return ReactiveMethod.call("myMethod", "a", "b");
        
        // Can also use 'apply' style
        // return ReactiveMethod.apply("myMethod", ["a", "b"]);
    }
});

Method results are updated every time their arguments change

Be careful! If you pass something like Random.id() or new Date() as one of the arguments, you will cause an infinite loop where the method is called infinitely over and over. If you don't want your method call to re-run on every argument change, try this other package: https://atmospherejs.com/mnmtanish/call

Invalidating method calls

Sometimes, you want to force a reactive method to get a new value from the server, even though the arguments are the same. In that case, use ReactiveMethod.invalidateCall or ReactiveMethod.invalidateApply, like so:

// Will cause the helper above to rerun
ReactiveMethod.invalidateCall("myMethod", "a", "b");

meteor-reactive-method's People

Contributors

dimda avatar ecwyne avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

meteor-reactive-method's Issues

Not working with ReactJS

Thanks for this package, but the one don't working with ReactJS (ReactMeteorData mixin).
For example:

React.createClass({
  mixins: [ReactMeteorData],
  getMeteorData() {
    return {
      count: ReactiveMethod.call('count')
    };
  },
  render() {
    return <div>{this.data.count}</div>;
  }
});

When we will try use this we will have an infinity loop. Fix it, please!

Infinite loops result if arguments to method calls evaluate differently on each run of the function

First, let's note that each return from the ReactiveMethod.call causes the function to be rerun.

i=1; Tracker.autorun( function(){ 
   console.log('run', i++);
   var c = ReactiveMethod.call("createCustomer", 2);
   if(c){
     console.log('c has value', c);
     var c2 = ReactiveMethod.call("createCustomerThing", c, {foo:'bar'});
     console.log(c2);
   }
})

This will print "run 1", "run 2", and "run 3", in general running a first time, then once for every method call. But it gets worse.. Because ReactiveMethod finds which value to return based on argument equality, if you run the following (note the new Date() in the args list for createCustomer)

i=1; Tracker.autorun( function(){ 
   console.log('run', i++);
   var c = ReactiveMethod.call("createCustomer", new Date());
   if(c){
     console.log('c has value', c);
     var c2 = ReactiveMethod.call("createCustomerThing", c, {foo:'bar'});
     console.log(c2);
   }
})

It will keep pinging the server forever, calling createCustomer with different arguments and never continuing on.
If there's a solution for this, I'd be interested.
If not, it would probably suffice to put a few caveats in the Readme to describe exactly what is going on with respect to rerunning the functions, because side-effecting calls and changing argument lists are definitely something to be avoided.

[feature] - trigger method to rerun

It would be useful to trigger ReactiveMethod to invalidate previously returned results and rerun.

Proposed API

Template.myTemplate.helpers({
  helperName: function (){
    return ReactiveMethod.call('methodName', 'a', 'b');
  }
})

//elsewhere
ReactiveMethod.invalidate('methodName', 'a', 'b');
//helperName reruns method and returns new result

Implementation

reactive-method.js

  ReactiveMethod = {
    call: ...
    apply: ...
    invalidate: function (/* arguments */){
      var cc = Tracker.currentComputation;
      //ensure computation existence, serialize args, etc...
      delete cc._reactiveMethodData[serializedArgs];
      cc.invalidate();
    }
  }

I am more than willing to implement this and create a PR. I believe this method could be called "invalidate" or "changed" or "rerun", did't know if you'd have any preferences or any other thoughts on implementing this API @stubailo

The helper only updates template on browser refresh

I implemented this library. It is working but the data only updates on template with browser refresh.

How I can make the data automatically update on client template without browser reload...

The only way the data updates on the template is with a full browser refresh. I was under the impression that when you use the word "reactive" it means that the helper will continue to stream a connection to the server side and keep any new data changes up to date on my template.

What am I doing wrong? Any help greatly appreciated.

[Feature] - Template Helper

I've found myself making loads of template helpers that simply return the result of a reactive method. I was thinking of creating a global helper to accomplish this which could easily be added to the package itself.

Implementation

Template.registerHelper('ReactiveMethodCall', function (methodName){
    return ReactiveMethod.apply(methodName, _.rest(_.toArray(arguments)));
});

Template.registerHelper('ReactiveMethodApply', function (methodName, args){
    return ReactiveMethod.apply(methodName, args);
});

Use

<template name="mySuperCoolTemplate">
  {{ReactiveMethodCall 'mySuperCoolMethod' 'arg1' 'arg2'}}
</template>

Could I check ready (waiting) form server?

I want to check ready or not, if server run for along time:

Template.foo.helpers({
   methodResult: function () {
           var result = ReactiveMethod.call("myMethod", "a", "b");
           if(result.ready()){
              return result; // this doesn't work!!!
           }else{
               return 'Loading...';
           }
       });
   } 
});

A helper runs multiple times

I find this package very useful. Thank you for it. Do you have an idea, how to fix running a helper multiple (four) times at every change of a Session variable, which stands in place of the argument of the ReactiveMethod?

Method rerunning even if args dont change

For some reason my meteor methods are being called even if I dont update the params.

Look at this for example

HTML


 <tr>
        <td>
          Assets : {{money totalBalance.assets}}
        </td>
        <td>
          Liabilities : {{money totalBalance.liabilities}} =
        </td>
        <td>

        </td>
      </tr>

JS

totalBalance : function () {
    var result = ReactiveMethod.call("getBalance", 'a');
    return result || { assets : 0, liabilities : 0 };
  }

on the server I am seeing the following happen


I20150806-13:46:47.886(-4)? a <- Param
I20150806-13:46:48.233(-4)? test <- random consolelog
I20150806-13:46:48.233(-4)? a <-Param
I20150806-13:46:48.554(-4)? test <- random consolelog

Any Ideas?

Getting the same (old) result returned

My call to reactive method works reactively but it's returning the same result it returned the first time (right after undefined) even though the server returns changed value.

If I invalidate (ReactiveMethod.invalidateCall()) the call right after the main call (ReactiveMethod.call()), it ends up in infinite loop unless I check for returned value being not undefined, but the final result is the same - no updated value returned.

Don't auto update when the Collection updated.

I have

// --------------Server
Meteor.methods({
   getData: function(){
      var data = Collection.Customer.find().fetch();
      return data;
   }
})

// ----------------Client
// Template
{{#each data}}
...............
{{/each}}

// Helper
data: function(){
   var data = ReativeMethod.calle('getData');
   return data;
}

Don't auto update, when I update collection.
Please help me.

Code evaluates key rather than check for its presence

On line 28, quoted below:

if (cc._reactiveMethodData && cc._reactiveMethodData[serializedArgs]) {

cc._reactiveMethodData[serializedArgs] should be _.has(cc._reactiveMethodData, serializedArgs) as in:

if (cc._reactiveMethodData && _.has(cc._reactiveMethodData, serializedArgs)) {

since the former is the value of the key, while the latter is checking for the presence of the key ... which is the condition I believe you were looking for. ;-)

Without this correction, I was getting infinite runs because the method I was calling returns booleans, and the if clause was not entered when the return value was false. Once I made the correction ... no more infinite runs.

Thanks for this package! It's just what I needed.

Comment:

Could you show an example if you had to feed the output of one Meteor.call into another ?

I might be convinced to retire a different package I'm using you could support this.

using with mdg:validated-method

Hi I tried to call reactive-method with the new way of defining methods using mdg:validated-method however it returns undefined. How can I use this with the new way of defining methods?

Template.foo.helpers({
methodResult: function () {
return ReactiveMethod.call("myMethod", "a", "b"); // returns undefined but with reactiveMethod.call returns well
}
});

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.