Just following the conversation along, trying to understand the different points of view. When you say, ‘However, there’s nothing stopping you from defining a Promise wrapper for the call.’, is the below an example of what you mean?
// server side
export const authorizationMSGraph = new ValidatedMethod({
name: 'msGraph.authorization',
validate: msGraph.omit(['msGraphInformation']).validator(),
async run ({ msGraphAction }) {
if (Meteor.isServer) {
switch (msGraphAction) {
case ('getToken'): {
const method = 'POST';
const url = 'https://login.microsoftonline.com/'
+ Meteor.settings.private.msGraph.tenantId
+ '/oauth2/token';
const headers = {
'Content-Type': 'application/x-www-form-urlencoded',
};
const params = {
'grant_type': Meteor.settings.private.msGraph.grant_type,
'client_id': Meteor.settings.private.msGraph.client_id,
'client_secret': Meteor.settings.private.msGraph.client_secret,
'resource': 'https://graph.microsoft.com',
};
return await HTTP.call(method, url, { headers, params });
}
default: {
throw new Meteor.Error(
'msGraph.authorization.failure',
`Method ${msGraphAction} was not recognized...`,
);
}
}
}
},
});
Just a small point about your HTTP.call: that does not return a Promise, so your await is not needed there. Instead that (non-callback) form uses Fibers to wait for completion. However, you could choose to wrap the callback form in a Promise and use await.
I’m trying to understand what will happen given that you sometimes have an args parameter and sometimes not. I don’t even know if that could cause what you’re seeing, but it may be worth rationalising your code for consistency and see if that makes a difference.
@robfallows Well, just in the example I posted, that method takes no arguments. It just returns a literal number, but the response, from the calling code, is undefined. So, although I know that kind of looks like it might be pseudo-code or example code, it’s actually code I wrote and executed to test the simplest possible situation. When I run that actual code, response is always undefined, though I can’t see any reason why that would happen.
Or maybe I’m not understanding your response…? Are you saying the code I’m showing should actually be working the way I expect, so there might be something else not accounted for?
The “advanced biolerplate” example does not return the result of the method invocation. It only counts on exceptions propagating through the stack (note their calling example, it only checks err, and else assumes everything went OK, never assumes a result value, as it is an update operation). If you want to return a value from the method, you should do so explicitly:
Thanks for your response. I had tried it with returning the value of Meteor.apply and still gotten undefined returned. At that point I thought perhaps apply doesn’t actually return the value from the callback, but maybe it somehow happened implicitly. Just because I had no other theory and was grasping at straws.
regarding this example line you show:
return TestMethod.run.call(this, args);
Where would that go? The client code is not inside a callback, so I don’t know what it would be returning to.
The apply part is meant for the client-side call. It allows you to have more control over the way the call is made, but you are not returning its value (it will return a value or raise an error from the client method stub due to the options you passed to apply).
Oh man. Of course, the actual Meteor.methods() registration! Somehow I completely missed the obvious SEVERAL times while trying to get this to work in the past. That’s the one place I forgot about. Thanks for your patience and help!
This, btw, is what I get for having created a Meteor Method factory that encapsulates the actual call to Meteor.methods() to register them. It made me forget about that part.
@sashko I would like to clear up sth about Method call life cycle. It’s written in the guide that if an error occurs during simulation on the client side, Meteor continues with server side operations (sending DDP package to the server, etc.). Why does Meteor continue with the server side operations in a failed case? Isn’t it waste of resources?
If an exception is thrown from the Method simulation, then by default Meteor ignores it and continues to step (2)…