Reputation: 1545
I am trying to return a response or a error on the client side from a meteor method that exists on the server side. The method itself is for submitting a post request to a API when a form is submitted, I would like to on the client side be able to return the API's response so I can send info to the user like, this email address already exists. Here is what I have so far.
I receive a 201 response on the client side in the console.log(result);
when I call the method when it is successful but I would like to also console log the error when the POST submissions gives a 400 or any error.
server/main.js
Meteor.methods({
addSub(email) {
var emailAddress = {
"lists": [
{
"id": "1395617465"
}
],
"email_addresses": [
{
"email_address": email
}
]
}
HTTP.post('https://api.constantcontact.com/v2/contacts?api_key=<api-key>', {
headers: {
'Authorization': 'Bearer <token>',
'Content-Type': 'application/json'
},
data: emailAddress
}, function (error, response) {
if ( error ) {
console.log( error );
throwError = error;
} else {
console.log(response);
returnResponse = response;
}
});
return returnResponse;
}
});
client/main.js
Template.info.events({
'submit #cm-subscribe'(event){
event.preventDefault();
var form = event.target;
var email = form.email.value;
Meteor.call('addSub', email, (error, result) => {
console.log(result);
});
}
});
client/main.html
<template name="info">
<h2>Signup For Our Newsletter</h2>
<form id="cm-subscribe">
<input field name="email" type="email" value="email">
<input type="submit">
</form>
</template>
Upvotes: 2
Views: 1210
Reputation: 4419
1) Your code currently contains a race condition. The value of returnResponse
may or may not be set depending on the order of execution between the callback and the return statement. Instead, you should use Promises, which allow you to wrap asynchronous code in a synchronous way. There is a good post on the Meteor blog about how to do this. Note that this does not affect the client behavior- it would still use callbacks like you have.
2) The reason that you do not see errors on the client is that Meteor intentionally converts all normal Javascript errors (like those returned by HTTP.post) into internal server errors to protect data and source code. What you should do is handle all of the errors on the server side, and return new Meteor.Error
objects for expected invalid responses. These can then be handled by the client. A thorough explanation of this can be found in the Meteor Guide.
Something like this:
Meteor.methods({
addSub(email) {
return new Promise((resolve, reject) => {
HTTP.post('<URL>', ..., function(error, response){
if(!error){
resolve(response);
} else if (error == <Some Error Comparison>){
reject(new Meteor.Error("Email.subscription.invalidEmail", "You put in an invalid email"));
}
});
});
}
}
Upvotes: 4