Reputation: 11
I'm trying to test the latency compensation by adding a delay in the server side code of a method that inserts a document in a collection. The idea is that when the method is running "mirrored" in the client, the title of the post inserted will have "(client)" concatenated to it, and then when the method runs in the server, it will have "(server)" concatenated to its title. Since I set a delay of 5 seconds for the server, I should see the post title changing proving how the latency compensation works.
The file I have implementing this method is under /lib/collections folder, so it should be accessible by both the server and client, however it doesn't work, I never see the "(client)" text in the titles, only "(server)" and the post doesn't show up until the 5 seconds have passed, so it seems that the client side code is not working, only the server one.
This is the source of the file (/lib/collections/post.js) where the method is defined:
Posts=new Mongo.Collection('posts');
Meteor.methods({
postAdd:function(postAttributes){
check(Meteor.userId(),String);
check(postAttributes,{
title:String,
url:String
});
if(Meteor.isServer){
postAttributes.title+=' (server)';
Meteor._sleepForMs(5000);
}else{
postAttributes.title+=' (client)';
}
var posWithTheSameLink=Posts.findOne({url:postAttributes.url});
if(posWithTheSameLink){
return {
postExists:true,
_id:posWithTheSameLink._id
}
}
var user=Meteor.user();
var post=_.extend(postAttributes,{
userId:user._id,
author:user.username,
submitted:new Date()
});
var postId=Posts.insert(post);
return {
_id:postId
};
}
});
And this is the source of the file (/client/templates/postAdd.js) where the event is triggered:
Template.postAdd.events({
'submit form':function(e){
e.preventDefault();
var post={
url:$(e.target).find('[name=url]').val(),
title:$(e.target).find('[name=title]').val(),
user_id:Meteor.userId
};
Meteor.call('postAdd',post,function(error,result){
if(error) return alert(error.reason);
if(result.postExists) alert('This link has been already posted.');
//Router.go('postPage',{_id:result._id});
});
Router.go('postsList');
}
});
If I add the following in the post.js file right after the Posts=new Mongo.Collection('posts');
:
if(Meteor.isClient){ alert('This is the client!'); }
I do see the message popping up, so the post.js file is definetely accessible by the client.
It seems that any client code inside the method definition won't work.
What am I doing wrong?
Thanks.
Upvotes: 1
Views: 122
Reputation: 2666
Being a beginner at Meteor, I was wondering the same thing.
I found some info regarding Method Life-Cycle, which you might find useful, here.
Also I tried running a simplified version of your code:
DB = new Mongo.Collection('db');
Meteor.methods({
'test': function(data) {
if (Meteor.isServer) {
data.title += ' (server)';
Meteor._sleepForMs(50000); // here I increased the delay just to be sure
} else {
data.title += ' (client)';
}
DB.insert(data);
if (this.isSimulation) { // logged the output before server response came
console.log(DB.find().fetch());
}
if (Meteor.isServer) {
console.log(DB.find().fetch());
}
}
});
This gave me the expected output. I got the (client)
output from the browser, data had been inserted into the client-side DB but not the server-side DB. Once, server-side DB got new data, my client-side document automatically changed to (server)
.
Upvotes: 0