Meteor.call not firing on the server, fine in the console - meteor

I have a server method:
server/methods.js
Meteor.methods({
removeStructure: function(id) {
this.unblock();
console.log("method removestructure was called on "+ id);
Structure.remove({"overlay_id": id}, function(error, result) {
if (error) {
console.log(error);
} else {
console.log("Deleted " + result + " structures.");
}
});
}
It is invoked in an observer when a document is removed from a collection:
client/x.js
Overlays.find().observe({
removed: function(item) {
console.log('Overlay removed' );
if ( Meteor.isClient ) {
drawnItems.eachLayer(function (layer) {
if (layer.meteor_id == item._id) {
drawnItems.removeLayer(layer);
}
});
}
console.log("attempting to remove meteor id " + item._id);
Meteor.call("removeStructure", item._id);
}
});
Nothing happens. The trace "attempting to remove meteor id jykkcEJuBL4NfJdte" fires, but the meteor method does not get called on the server. No error is returned client or server, it's as if it skips clean over that line.
When I type into the client browser console
Meteor.call("removeStructure", "jykkcEJuBL4NfJdte");
It runs no problem on the server and client.
What could be going wrong here? Am stumped!

Related

Meteor Method w/ Mongo Aggregation returning Undefined on Client but not on Server

So I've just started with Meteor and really JavaScript so forgive the messy coding as I am new to all of this please. I'm using a Mongo Aggregation to do some server side math and the method is returning undefined on the client but the server-side console log is returning the correct information. Here is the server method...
Meteor.methods({
'schoolHealth': function() {
var pipeline = [
{
"$group": {
"_id": null,
"total": { "$avg": "$roomHealth"}
}
}
];
Equipment.aggregate(pipeline, function(err, result) {
if (err) {
throw err;
console.log("Error in finding school health average:" + result);
} else {
console.log(result[0].total)
return result[0].total;
}
});
}
});
And on the client...
Meteor.call('schoolHealth', function(error, result) {
if (error) {
console.log(error);
} else {
console.log(result);
Session.set('health', result);
}
});
I'm calling the Session on a blaze template but the method is failing before that happens. Also, I have tried not using a Session and the result is the same. I have read into Sync vs. Async but I don't know enough about it to know if I am doing something wrong there. Thanks ahead of time for the help.

Extracting data out of http call [duplicate]

I'm using Meteor for first time and i'm trying to have a simple http call within a method so i can call this method from the client.
The problem is that this async call it's keep running even if i put it within a wrapper.
Client side:
Meteor.call('getToken', function(error, results) {
console.log('entered');
if(error) {
console.log(error);
} else {
console.log(results);
}
});
Server Side
Meteor.methods({
getToken: function(){
// App url
var appUrl = 'myAppUrl';
// Key credentials
var apiKey = 'mykey';
var apiSecret = 'mySecret';
function asyncCall(){
Meteor.http.call(
'POST',
appUrl,
{
data: {
key: apiKey,
secret: apiSecret
}
}, function (err, res) {
if(err){
return err;
} else {
return res;
}
}
);
}
var syncCall = Meteor.wrapAsync(asyncCall);
// now you can return the result to client.
return syncCall;
}
});
I'm always getting an undefined return.
If i log the response within the http.post call i'm geting the correct response.
If i try to log the syncCall i get nothing.
I would very appreciate any help on this.
You should use the synchronous version of HTTP.post in this case. Give something like this a try:
Meteor.methods({
getToken: function() {
var appUrl = 'myAppUrl';
var data = {apiKey: 'mykey', apiSecret: 'mySecret'};
try {
var result = HTTP.post(appUrl, {data: data});
return result;
} catch (err) {
return err;
}
}
});
Instead of returning the err I'd recommend determining what kind of error was thrown and then just throw new Meteor.Error(...) so the client can see the error as its first callback argument.

Can't catch meteor error thrown in Method from Event

I have a method and it throws an error so I can catch it in my event and display it to the user, like this:
Meteor.methods({
addPlayer: function(nickname) {
if (nickname == "") {
throw new Meteor.Error('empty-nickname', 'You must choose a nickname');
} else {
Player.insert({
nickname: nickname,
});
}
},
})
and in my event
'submit form': function (e) {
e.preventDefault();
var nickname = $('input').val();
Meteor.call('addPlayer', nickname, function(error, result) {
if (error) {
console.log(typeof error);
console.log(error);
}
});
}
However, meteor still throws an Exception while simulating the effect of invoking 'addPlayer', and the error variable is not an error object, but a string with the same message as the console log, so I get two errors in my console instead of an error object.
Wrapping method.call in a try/catch does not work.
What am I missing here?
-- Edit
Here is an print screen of the result:
Image link for full resolution: http://i.stack.imgur.com/zABar.png
Throw the error only on the server. Wrap it inside if(!this.isSimulation) {}
Meteor.methods({
addPlayer: function(nickname) {
if (nickname == "") {
if(!this.isSimulation) {
throw new Meteor.Error('empty-nickname', 'You must choose a nickname');
}
} else {
Player.insert({
nickname: nickname,
});
}
},
})

Accounts.createUser on server does not return response to client

I'm attempting to use Meteorjs Accounts on the server to create a new user and then send them an email to set their initial password. The idea is that an admin user can add new users.
I can successfully add the new user (I can see the new user ID in the server console if I log it), but that ID is never returned to the client. This is my server-side
Meteor.methods({
createNewUser: function(email){
return Accounts.createUser({email: email});
}
});
And the relevant client-side JS:
if (isNotEmpty(email) && isEmail(email)) {
Meteor.call("createNewUser", email, function(ret){
if (typeof ret.message !== 'undefined') {
if (ret.message === 'Email already exists. [403]') {
alert("exists");
} else {
alert("not created");
}
} else {
Accounts.sendEnrollmentEmail(ret, function(err){
if (err){
alert("email didn't get sent");
} else {
alert('success');
}
});
}
});
}
I get this in my browser console:
Exception in delivering result of invoking 'createNewUser': TypeError: Cannot read property 'message' of undefined
It's probably worth noting that I also get the "exists" alert if I try to submit the same email address twice in a row, so the error is getting returned to the client just fine.
The first argument in callback is always error object.
error equals null if everything is fine.
Meteor.call('createNewUser', email, function( error, result ){
if( error ){
console.error("ERROR -> ", error )
}else{
console.log("User was created!")
}
})
but that ID is never returned to the client.
Thats because you don't have any console.log on the client. also the meteor call look incorrect.
if (isNotEmpty(email) && isEmail(email)) {
Meteor.call("createNewUser", email, function(err,result){
if (typeof ret.message !== 'undefined') {
if (ret.message === 'Email already exists. [403]') {
alert("exists");
} else {
console.log(result) //here for example you should get the id
}
} else {
Accounts.sendEnrollmentEmail(ret, function(err){
if (err){
alert("email didn't get sent");
} else {
alert('success');
}
});
}
});
}

Meteor methods wait before execution on client proceeds

could anybody please tell me how to make clients wait until the called function on the server is executed?
My code:
Meteor.methods({
markLettersAsRead: function(userId) {
if(serverVar) {
Users.update({_id: userId}, {$set: {letters: []}}); // removing all references
}
}
});
Template.letter.events({
'click a': function() {
Meteor.call('markLettersAsRead', Meteor.userId(), this._id, function(err) {
if (err) {
console.log(err);
}
});
var usersExistsWithThisLetter = Users.find({letters: {_id: this._id}}).count();
console.log(usersExistsWithThisLetter);
}
});
In my example usersExistsWithThisLetter is always 1 because the Users.find() doesn't wait until the Meteor.call is done. I verified this by checking the database and no users exists with entries in the letters array.
Any help would be greatly appreciated.
You need to query the collection inside the callback, because then you can be certain that your server method has already been executed. I would do something like this (note the self variable declaration):
var self = this;
Meteor.call('markLettersAsRead', Meteor.userId(), this._id, function(err) {
if (!err) {
var usersExistsWithThisLetter = Users.find({letters: {_id: self._id}}).count();
console.log(usersExistsWithThisLetter);
} else {
console.log(err);
}
});
I hope it helps!

Resources