Jeanluca Scaljeri
Jeanluca Scaljeri

Reputation: 29199

Meteor: How to return data from the server using Meteor.call

When I do the following on the client:

Meteor.call('fileUpload', fileInfo, fileData, function(err, response) {
    ....
});

In the callback I need the response. So on the server I have

Meteor.methods = {
   fileUpload: function (fileInfo, fileData) {

   fs.writeFile(path, fileData, "binary", function (err) {
       if (err) 
           return 'error';
       ...
       return { ..... };
  }
  //return 'this works';

}

Unfortunately I don't receive anything on the client. The problem is that the server runs async code (fs.writeFile). If I uncomment the last line I receive something back. So the question is: can I return something back to the client when I run async code ?

Upvotes: 0

Views: 821

Answers (2)

Marco de Jongh
Marco de Jongh

Reputation: 5458

Meteor uses fibers to allow async code to be written in a sequential way to prevent ending up in callback hell. They provide future as abstraction layer to fibers.

var Future = Npm.require('fibers/future');
var result  = Future.wrap(fs.writeFile)(path, fileData, "binary").wait();

This wraps the async writeFile method in a fiber.

Read the following article for better explaination of how fibers work:
http://meteorhacks.com/fibers-eventloop-and-meteor.html

The meteor team doesn't recommend using the raw fibers api. Src: https://www.npmjs.org/package/fibers section about futures

Async.wrap and Future.wrap basically do the same thing. But there is one big difference Async.wrap hides the future and doesn't make you use .wait() because the wrapped function doesn't actually return the future but returns whatever the future returns.

In the end you can use both I would personally favor future.wrap because I like to be aware of that I am working with fibers & futures and I do not like that being hidden from me.

var wrappedSomeMethod = Async.wrap(someMethod);
wrappedSomeMethod();

Is less verbose than:

var wrappedSomeMethod = Future.wrap(someMethod);
wrappedSomeMethod().wait();

Advanced future use

And it also lets you run multiple things in different futures example:

var fooFuture = bar();
var wuFuture = bar();

var fooResult = fooFuture.wait();
var wuResult = wuFuture.wait();

Should be faster because you are not pausing the current fiber to start the next

Upvotes: 4

zhaoyou
zhaoyou

Reputation: 308

have a try:

var writeFile = function(fileinfo, fileData, callback) {
   fs.writeFile(path, fileData, "binary", function (err) {
   if (err) 
       callback('error');
    ....
   callback(null, 'good')
   }
}


Meteor.methods = {
   fileUpload: function (fileInfo, fileData) {
      var result = Async.wrap(writeFile)(fileInfo, fileData);
      return result;
   }
}

Upvotes: 1

Related Questions