Start using async/await instead of promises and callbacks

Why are there not that many actual MeteorJS server side examples? Tried to use async and await and was wondering why results are not ordered as expected when I clicked on a button?

In my case the client/main.js:

Template.resultfromACS.events({
'click .get_id' (event, instance) {
      (async function () {
          var result1 = await Meteor.callPromise('getXml', '123456789=', 'seb'); 
          var result2 = await Meteor.callPromise('testFunction', result1);
       }());
   } 
});

in server/main.js:

Meteor.methods({

    getXml : async function (authorizationCode, username) {
        var url = "".concat("https://myHost/Rest/Identity/User/name/",username);
        var req = unirest("GET", url);
        req.headers({
        "content-type": "application/xml",
        "authorization": "".concat("Basic " ,authorizationCode)
        });
        await req.end(function (res) {
            if (res.error) throw new Error(res.error);         
            console.log('res.body is :', res.body);  
        });  
      }, 

      testFunction: async function (message) {
            console.log('Message is : ', message);
      }
});

Results in:

Message is : null
res.body is :<?xml version=“1.0” encoding=“UTF-8” standalone=“yes”?

Why is the second call to testFunction happening before the first call to getXml in this case, as I need to get result from first call and pass result1 into second method?


Would this be something better to use than async/await?

You can use them together with the promise mixin: https://atmospherejs.com/didericis/callpromise-mixin

So you could do:

await myMethod.callPromise(args);

And there’s a variety of other mixins as well! https://github.com/meteor/validated-method#community-mixins

thanks @sashko but how do you do it on the client? I’m getting stuck with this.

Async/Await is not supported on the meteor client, what can we use? Should I wrapasync the method?

I thought it was in Meteor 1.3, no?

1 Like

For people who are using Angular2-Metoer, I recommend using the built-in RxJS 5 (Observable) which is much more powerful!

Also, I posted it here about how to Subscribe data in Service using RxJS 5 which gives you a feel to start using the more powerful RxJS 5.

Hi, tried async with Meteor 1.3.3.1.
async function(...argus)=>{ // console.log("call"+id); return callMeteorMethod(name,...argus); }
Got an error:
Unexpected token (49:38)

What am I missing here? Any extra package to support this?

Thanks!

You’re using the arrow function syntax incorrectly by also typing the function keyword.

My Bad! Still not familiar with the new js. Thanks! It works!

1 Like

How I can manage the following?

  1. When Meteor.call for validateObject is triggered
  2. Waterfall goes thru the callbacks
  3. At last the final result of the waterfall is returned to the Meteor.call via Meteor.method function and printed into console.log

This would be super useful :smile_cat:

var async = require("async");
var waterfall = require("async/waterfall");

  Meteor.methods({
    'validateObject': function(object) {
      async.waterfall([
        function(callback)  {
          // run first 
          callback(null, result);
        },
        function(result, callback)  {
          // run second
          callback(null, result);
        }
      ], function(error, result) {
          // at the end provide return to Method 'validateObject';
      });
    }
  });

  var object = {_id: "string", name: "string"}

  Meteor.call("validateObject", object, function(error, result){
    if(result) {
      // Display the return from Method 'validateObject';
      console.log(result);
    }
  });

Hello @trusktr I am little confused about using async/await in meteor method in server side
I am trying this code, but doesn’t works:

const requestWithPromise = async (options) => {
  // Axios create a promise to return request result: https://www.npmjs.com/package/axios
  const result = await axios(options); 
  console.log('showing axios result', result.data);
  return result.data;
};

Meteor.methods({
  'Request.execute'(data) {
    const options = {method: 'post', url, data, timeout};
    const result = requestWithPromise(options);
    console.log('showing myPromise result' , JSON.stringify(result));
    return result;
  }
});

In my meteor method I should wait for request result, but the log order is the following:

showing myPromise result {}
showing  axios result {id:.............}

You’re missing the await:

const result = await requestWithPromise(options);

Hi @sashko, I can’t use await inside a meteor method, because I should define the method as async and it generates error, but I fixed my problem with a simple thing:

  'Request.execute'(data) {
    const options = {method: 'post', url, data, timeout};
    const response = Promise.await(axios(options));
    console.log('SHOWING ASYNC' , JSON.stringify(response.data));
    return response.data;
  }

I am working with Meteor@1.4.2.
This is the required package https://github.com/meteor/promise

1 Like

@sashko Meteor supports async methods now?

1 Like

Yes - this sort of thing is supported:

Meteor.methods({
  async someMethod(x, y) {
    const a = await someAsyncFunction(x);
    return await someOtherAsyncFunction(a, y);
  }
});

@robfallows have you actually done that? Based on what @ilacyero reports:

… I can’t use await inside a meteor method, because I should define the method as async and it generates error …

1 Like

Yes. It works exactly as it should when called from the client (the Promise is resolved before the result is sent back over the wire).

When I was playing with this a few months back I got unexpected results (the Promise itself) when calling an async method from within the same server code (not something I normally do).

Hm, so given a methods-calling-methods situation, eventually some of those methods will be getting called form the server as well. And then it might (based on what I understand from your experience) cause issues, right?

Perhaps. I found that behaviour, but I haven’t revisited those tests for quite a while, so it may be fixed now. I should probably take another look. I was putting a repro together for @benjamn, but got sidetracked and didn’t finish it. :disappointed: