Meteor.call is very slow when responding back - meteor

I am facing performance problem with Meteor.call(). I have a method on server side which gets execute within a millisecond but when I seek a response in the client side, it is taking long to get the response data inside the callback function. Is anyone experience the problem before?
I was using Meteor 1.12.1 and updated to Meteor 2.1.1 hoping to solve the problem by updating but I didn't find any difference.
Update: I am facing issue on all environment (osx, linux, windows).
For eg: This is my server code
Meteor.methods({
newEntry() {
//This method is executed within millisecond
}
})
This is my client code
function submitEntry(data) {
Meteor.call(
'newEntry',
data,
(error, res) => {
//Here I am getting the response after long wait.
},
);
}
Can somebody help me on this?

I found the solution. As per the Meteor docs.
Once the Method has finished running on the server, it sends a result message to the client with the Method ID generated in step 2, and the return value itself. The client stores this for later use, but doesn’t call the Method callback yet. If you pass the onResultReceived option to Meteor.apply, that callback is fired.
Ref: https://guide.meteor.com/methods.html#advanced-boilerplate
So if you want your call back to be triggered once the server method return the value then you can use Metor.apply method with the option onResultReceived.
Meteor.apply(
"methodName",
[...params],
{
onResultReceived: function() {
// Whatever you want to do after callback.
}
}

Related

Session is not defined within Meteor.methods on server side but is on client side [duplicate]

This question already has answers here:
Meteor Session is not defined
(4 answers)
Closed 7 years ago.
I have a method that sets the session variable:
Meteor.methods({
updateSomething: (k) => {
CollectionOfSomething.insert({
k: k
});
Session.set('latestSomething', CollectionOfSomething.findOne({
k: k
});
}
});
What happens next is something contradictory to me. Since the methods are defined within lib folder (which is a correct way to do), a call invokes the method both on client and on the server. On the client, it yields new value for the session variable latestSomething, and it refreshes every time. But on the server, I'm getting an exception:
Exception while invoking method 'updateSomething' ReferenceError: Session is not defined
This exception is just a warning and doesn't kill the app instance. But it seems not a good practice, and all those messages stuff the server logs without any value.
What should I do then? What's the Meteor idiomatic way to do?
You can't use session on the server. It's meant for reactivity on the client. Set it on the callback like so:
Meteor.call('updateSomething', yourThing, function (err, id) {
if (!err) {
Session.set('somevar', id);
}
})
where your meteor method looks like this
Meteor.methods({
updateSomething: function (thing) {
return MyCollection.insert(thing); // returns the id
}
});
The Session object is only available on the client (see http://docs.meteor.com/#/basic/session - both of the function definition boxes say "Client"). Your best option is to return the result of your CollectionOfSomething.findOne() fetch and then use Session.set in the client's callback function.
The Session is an ephemeral object that is lost on a hard page refresh or when the user manually navigates to a different page, so maintaining it on the server wouldn't make any sense.

Meteor wrapAsync works, but restarts server after completion

I'm trying to learn how to use Meteor's wrapAsync helper. I want to use it to call an async function sequentially (not simultaneously). Though my code works, when it completes, the server restarts, which makes me wonder if there is a bug in my code. Unfortunately, there is no message saying why it restarted. Am I missing something?
The code is below and also on my MeteorPad demo.
var doAsyncIO = function (num, callback) {
setTimeout( function () {
// wrapAsync will use the following callback as the basis of returning results synchronously
callback(null, 'This is delayed result #' + num ); // nodeJS form: cb(error,result)
}, 2500); // wait 2.5 seconds before returning result
};
// Now create a synchronous version of doAsyncIO that sleeps, not blocks
// so that the CPU can do other tasks while waiting for the result
var doSyncIO = Meteor.wrapAsync(doAsyncIO);
// Now call doSyncIO twice sequentially (not simultaneously)
console.log('\n*** Starting first call to doSyncIO');
var result1 = doSyncIO(1);
console.log('result1:', result1);
// The following block runs after result1 is set (which is what I want)
console.log('\n*** Starting second call to doSyncIO');
var result2 = doSyncIO(2);
console.log('result2:', result2);
After a code change and after the console logs appear on the terminal, the terminal says the server restarts with no reason provided which makes me wonder if there is a bug in my code!
2015-04-19 Update: the restart message may not actually indicate a problem since it only shows up after a code change. Perhaps it's simply the standard restart message. Nevertheless, it seems like the restart message should really occur before the console logs.
Feel free to comment or fork my MeteorPad demo though to see if it's something else.

MeteorJs "loginWIthPassword" seems not to work in method

It seems that the "Meteor.loginWithPassword" function does not work when called in a method.
I want to create my login form with autoforms and so I created a callback method which get called after a user submitted the login form. The form gets called the right way but the loginWithPassword function does not seems to work.
This is my method (on Client & Server side)
Meteor.methods({
autoform_test_login : function (doc) {
console.log('Called login method');
if (Meteor.isClient) {
Meteor.loginWithPassword('test', 'test', function(e) {
if (e) {
console.log(e);
}
});
}
}
});
My autoforms calls this method when submitting with:
{{#autoForm schema="Schema_Login" id="form_login" type="method" meteormethod="autoform_test_login"}}
....
When submitting this form I get this error:
Error: No result from call to login {stack: (...), message: "No result from call to login"}
When I now open my Browser console and type in:
Meteor.call('autoform_test_login');
I will get the same error.
But: When I type the following in my console it works (The error now is: Username not found):
Meteor.loginWithPassword('test', 'test', function(e) {
if (e) {
console.log(e);
}
});
My method do absolutely nothing else then this snipped so I am asking myself whats going wrong here.
Ps.:
I know that I added the "test" as Username and "test" as password - its just to test. Even when the input is the right the error is always the same.
Okay, so I got a response and now I know why this is not working as expected.
loginWithPassord may only be executed on the client.
When you use Meteor.methods on the client, it will still run the functions you define within it on the server. That is why it won't work to have the loginWithPassword call within a Meteor.methods function.
Simply use this function anywhere else on the client. For example - directly within some template event.
Took me like forever to find out why it wasn't working.
Make sure that autoform is actually passing the correct values. If you've made a mistake in you're schema setup it will automatically clean the values (set to undefined) without throwing an error.
I'm also not entirely sure if using it with method set will work in this case, as you want to do the login call on the client not the server (I think).
Make sure your current Meteor instance has an active connection with the mongo database pointed to by variable MONGO_URL. Meteor.loginWithPassword fails to give error feedback when this connection gets closed or broken.

How to get the array in ajax success function

I have passed array as return array($posts,$count) from my ajax file.
now in success function i wnat both this array
How to get this array in my success function
I have written as below but i dont get any this in my console :(
in my ajax_post.php
return array($posts, $count);
jQuery.ajax({
url: 'http://localhost/abc/wp-content/themes/directory/Templates/ajax_post.php',
data: {
'action':'example_ajax_request',
'city' : city
},
success:function(data,count) {
// This outputs the result of the ajax request
console.log(data,count);
//loadPopup(data);
},
error: function(errorThrown){
console.log(errorThrown);
}
});
If your success function is not logging anything at all in your console, then it probably isn't getting called at all.
What do you see in your console? Do you get an error message after your ajax call? What if you try to just copy / past your jQuery.ajax call directly in the console, what happens then?
It's a bit hard to answer here without details of your function on the PHP side and without error messages, but I suggest you try to first return a simple data type from PHP (just a mock value) to make sure your function is indeed getting called and returns properly when called. If that works then you know your problem is with the data type your are returning. If it doesn't, then the problem is with your AJAX call.
You might very well be having problems with AJAX requests because you are doing them on localhost and that might be causing Cross-Domain request problems.
This question / answer actually explains the concept and the solution to that very well. I think you should at least get a reply to your request if you do that : Make cross-domain ajax JSONP request with jQuery

When is the "null" publish ready?

Having the following code on the server:
Meteor.publish(null, function(){
// Return some cursors.
})
will according to the documentation have the following effect: the record set is automatically sent to all connected clients.
How can I on the client side determine if all the documents published by this function has been received? If I would use a subscription instead, it would provide me with a ready callback, letting me know when all the documents been received. What's the matching way here? Or are the documents already received at the client when my client side code starts to execute?
I'm afraid there's no way to have a ready callback for so called universal subscriptions you mentioned above. Just have a look at this part of Meteor's code, where the publish and subscription logic is defined on the server. For convenience I'm copy/pasting the code below:
ready: function () {
var self = this;
if (self._isDeactivated())
return;
if (!self._subscriptionId)
return; // unnecessary but ignored for universal sub
if (!self._ready) {
self._session.sendReady([self._subscriptionId]);
self._ready = true;
}
}
The _subscriptionId is only given to named subscriptions, which are those that you would manually define using Meteor.subscribe method. The subscriptions corresponding to null publish functions, doesn't have their own _subscriptionId, so as you can see from the code above, the server is not event trying to send the ready message to the client.

Resources