Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make Meteor methods synchronous?

I need a way for a meteor call to be synchronous so that when a call is run, the code waits for a result to be done so it can continue to the next line of code on the client.

for example:

clientFunction = function(){

    Meteor.call('serverFunction', function(err,result){})//<--so when this gets a result and    
                                                    //is stored in a session variable
    var doSomeThing = Session.get('whatever') <-- so that your able to use it here
}

I've tried using a while loop to prevent anything from happening until a value is returned, but it seems like it runs after the clientFunction thus throwing it to its demise

any help would be appreciated

like image 424
cronicryo Avatar asked Mar 26 '14 17:03

cronicryo


People also ask

Are meteors asynchronous?

In Meteor, your server code runs in a single thread per request, not in the asynchronous callback style typical of Node.

How do I call Meteor method?

// Asynchronous call Meteor. call('foo', 1, 2, (error, result) => { ... }); If you do not pass a callback on the server, the method invocation will block until the method is complete. It will eventually return the return value of the method, or it will throw an exception if the method threw an exception.

What is Meteor defer?

defer is to run a task asynchronously. Let's say we have an app where we are sending an email. On the server, it may take several seconds for that to process inside of a meteor method, slowing down your application drastically. However, if you wrap that process in a Meteor.


3 Answers

This is a very common question, being asked in various shapes and forms. Most people don't realize when they are making asynchronous calls. The solution, however, is always the same: wrap your method code on the server into a fiber or use a future.

The best practice, I think, is to use the currently available Meteor._wrapAsync function as described, e.g., here: Meteor: Calling an asynchronous function inside a Meteor.method and returning the result

Some other options are described here: https://gist.github.com/possibilities/3443021


Update: The method is now called Meteor.wrapAsync.

like image 106
Christian Fritz Avatar answered Feb 11 '23 16:02

Christian Fritz


Put the code that you want to run after the method completes into the method callback. This is standard for any asynchronous javascript.

clientFunction = function(){
  Meteor.call('serverFunction', function(err, result){
    if (err) {
      alert(err);
    } else {
      Session.set('whatever', result.whatever);
    }
  });
};

That sets the value of the session variable once the method call returns. Now you use Meteor's reactivity to use that variable:

Template.hello.helpers({
  myWhatever: function () {
    var whatever = Session.get('whatever');

    if (whatever) return whatever;

    return 'Loading whatever...';
  }
});
like image 24
alanning Avatar answered Feb 11 '23 15:02

alanning


I followed this tutorial and do something like below

This is a meteor server side method

productIdResult:function(searchstring)
{
   {
      var skimlinks_query = Async.wrap(skimlinks.query);
      var title_val="title:\"electric bicycle\"  AND merchantCategory:*bikes*";                     
      var result = skimlinks_query({
                        searchFor: searchstring,
                        start:start,
                        rows:rows,
                        fq: "country:US"
                    });
      return result;
}

And I call it from client like this

Meteor.call('productIdResult',
            searchstring,
            function(error,resul)
            {
                arr[0]=resul.skimlinksProductAPI.products[0].title;
                $( "#op1").autocomplete({source:arr});

            }
);

Note that it is not synchronous, but you get the return value in the callback

like image 32
Sasikanth Avatar answered Feb 11 '23 15:02

Sasikanth