Using Meteor.wrapAsync correctly

Hopefully this is a newbie question.
I have the following code that I am trying to convert to using meteor.wrapAsync. I am getting a “Exception while invoking method ‘emailSend’ ReferenceError: syncfunc is not defined” exception. What am i missing?

stacktrace:

I20191031-06:21:16.246(-5)? Exception while invoking method 'emailSend' ReferenceError: syncfunc is not defined
I20191031-06:21:16.248(-5)?     at MethodInvocation.emailSend (src/imports/api/email.js:13:27)
I20191031-06:21:16.249(-5)?     at maybeAuditArgumentChecks (packages/ddp-server/livedata_server.js:1771:12)
I20191031-06:21:16.273(-5)?     at DDP._CurrentMethodInvocation.withValue (packages/ddp-server/livedata_server.js:719:19)  
I20191031-06:21:16.275(-5)?     at Meteor.EnvironmentVariable.EVp.withValue (packages\meteor.js:1234:12)
I20191031-06:21:16.276(-5)?     at DDPServer._CurrentWriteFence.withValue (packages/ddp-server/livedata_server.js:717:46)  
I20191031-06:21:16.277(-5)?     at Meteor.EnvironmentVariable.EVp.withValue (packages\meteor.js:1234:12)
I20191031-06:21:16.277(-5)?     at Promise (packages/ddp-server/livedata_server.js:715:46)
I20191031-06:21:16.278(-5)?     at new Promise (<anonymous>)
I20191031-06:21:16.279(-5)?     at Session.method (packages/ddp-server/livedata_server.js:689:23)
I20191031-06:21:16.280(-5)?     at packages/ddp-server/livedata_server.js:559:43

email.js:

Meteor.methods(
{
  emailSend(fromAddress, subject, emailText) 
  {
    if (Meteor.isServer) 
    {     
      const { Email } = require('../server/email.js');
      var syncFunc = Meteor.wrapAsync(Email.send); 
      var sendEmailReturn=syncfunc(fromAddress, subject, emailText);      
      return sendEmailReturn;
      **//if I comment out the above three lines and uncomment the line below then the application works fine.** 
      //return Email.send(fromAddress, subject, emailText);      
    }
  },  
})

You declare this as syncFunc, but use it as syncfunc.

Additionally, it’s often necessary to ensure the scope of the wrapped function is also set in the wrapAsync. I would rewrite your code to something like:

Meteor.methods(
  {
    emailSend(fromAddress, subject, emailText) {
      if (Meteor.isServer) {
        const { Email } = require('../server/email.js');
        const syncFunc = Meteor.wrapAsync(Email.send, Email);
        const sendEmailReturn = syncFunc(fromAddress, subject, emailText);
        return sendEmailReturn;
      }
    },
  });
1 Like

Thank you @robfallows. I need to drink some coffee before I post questions. :frowning:

1 Like

The best way to use Meteor.wrapAsync is to not use it and instead manage with Promises ahah !

===> I’m leaving already

2 Likes

Does Email.send have the right signature? I always thought it just ran synchronously (in a Fiber), and didn’t return anything. The docs aren’t perfectly clear…

Yes Meteor’s Email.send is synchronous, but in this case Email comes from user code, so it’s likely not the version given by Meteor: