Returning a value from a method using promises

Hi all,

I have a meteor method calling an API which is using promises. When the promise is resolved, I need to store some data in DB and return it to the client.

The code below returns the data correctly, but I can’t call Collection.insert(…) since code must run in a fiber:

return api.create({
  ...
}).then((data) => {
  console.log('Promise resolved', data);
  return data;
}).catch((e) => {
  console.log('Promise failed', e);
  throw new Meteor.Error(500, 'There was an error processing your request');
});

So I’ve added a Meteor.bindEnvironment:

return api.create({
  ...
}).then(Meteor.bindEnvironment((data) => {
  console.log('Promise resolved', data);
  return data;
})).catch((e) => {
  console.log('Promise failed', e);
  throw new Meteor.Error(500, 'There was an error processing your request');
});

But now, the data is not returned to the client; both the error and result are undefined.

Am obligated to use Promise.await to make the promise synchronous ?

Thanks!

Anyone ? - -------- ~~

Meteor’s inbuilt Promises work with Fibers/Futures, but 3rd-party Promises don’t. I would probably try using the rawCollection().insert method which returns Promises, rather than try to use bindEnvironment. So, instead of Collection.insert(...) try using Collection.rawCollection().insert(...) (the non-callback form). You will need to make sure you format the parameters for that according to the underlying library’s requirements - and call it as part of the Promise chain, or by using async/await appropriately.

Alternatively, I think it should be possible to “cast” a 3rd-party Promise into a Meteor Promise, in which case it will work as expected with Meteor’s Collection.insert.

EDIT: Check this as well:

Thank you for your inputs. I’ll try that !

@robfallows Could you please elaborate on the cast part ?

Here’s the API I’m using https://github.com/Mangopay/mangopay2-nodejs-sdk

This may help (I show the “casting” process towards the end).