Meteor Helpers - a function to check if document exists - meteor

The following code works as intended, ie the helper returns true if there is a document and false if there is no document. However, i am getiing a warning on my console.
"Error: Exception in template helper:
TypeError: Cannot read property 'filepickerId' of undefined
at Object.Template.navigation.helpers.ichk..."
The warning is inconsistent and not sure why that i the case. Once again, the code however works without any flow that i can tell.
Template.nav.helpers({
'ichk': function(){
var ct= Info.findOne({_id:Meteor.userId()});
if (ct.profilepic.filepickerId) {
return true;
}else{
return false;
}

You need a guard. Your helper can be rewritten like this:
Template.nav.helpers({
ichk: function () {
var ct = Info.findOne({ _id: Meteor.userId() });
return !!(ct && ct.profilepic && ct.profilepic.filepickerId);
}
}

If it works you should add one more line in order to get rid of the exception.
Template.nav.helpers({
'ichk': function(){
var ct= Info.findOne({_id:Meteor.userId()});
if(ct){
if (ct.profilepic.filepickerId) {
return true;
}
else{
return false;
}}
In this way you first check if the document exists.

Related

How to use findOne in Template onCreated and access it in helper

Here is my template onCreated and helper function. I have provided inline comments to add some clarity. I can see that self.post is eventually set because it shows up on my console when I log Template.instance(). However, when I log Template.instance().post, it is always undefined.
Template.default.onCreated(function() {
var self = this;
self.autorun(function() {
var postId = FlowRouter.getParam('post_id');
self.subscribe('onePost', postId);
self.post = Posts.findOne(FlowRouter.getParam('post_id'));
});
});
Template.default.helpers({
poststage: function(stage) {
console.log(Template.instance()); // I can see post object here
console.log(Template.instance().post; //always undefined
if(Template.instance().post) {
// never true
return Template.instance().post.stage == stage;
}
}
});
Template.default.events({
'submit form':function(event, instance) {
Meteor.call('someFunc', instance.post.anotherField);
}
});
Edit: I should add, I'm trying to avoid writing the query twice because I'm also using it in the Template events. (see code).
This feels like a timing issue. You are subscribing to the onePost publication but you aren't waiting for that subscription to be .ready() before assigning self.post The autorun also seems superfluous. You shouldn't need to rerun that block of code in the onCreated block. I suggest:
Template.default.onCreated(function() {
this.postId = FlowRouter.getParam('post_id');
self.subscription = subscribe('onePost', this.postId);
});
Template.default.helpers({
poststage: function(stage) {
if ( this.subscription.ready() ){
return Posts.findOne(this.postId).stage;
}
}
});

ironRouter onbeforeaction gives 2 errors, but does what I expect it to do

Users login using FB or twitter:
I'm trying to check for multiple things here as you can see. But for some reason I get 2 errors:
1. Exception in callback of async function: TypeError: Cannot read property 'profile' of undefined
2. Route dispatch never rendered. Did you forget to call this.next() in an onBeforeAction?
The funny thing is, this code IS doing what I expected it to do. Route to completeSignup if profile.firsttime = false and if not logged in go to startPage. But I still get these errors, so I must be doing something wrong.
code:
onBeforeActions = {
loginRequired: function() {
if (!Meteor.userId()) {
Router.go('startPage');
} else {
if (Meteor.userId() && Meteor.user().profile.firsttime) {
Router.go('completeSignup');
}
}
this.next();
}
};
Router.onBeforeAction(onBeforeActions.loginRequired, {
except: ['startPage']
});
Meteor.userId() becomes available as part of the login process prior to the arrivial of the user document on the client. Mixing the two in the if actually doesn't do what you want because, for a brief moment, they won't simultaneously return truthy values.
In order to avoid the error you'll need to add some extra guards. Try something like this in your else clause:
var user = Meteor.user();
if (user && user.profile && user.profile.firsttime) {
Router.go('completeSignup');
}

wrapAsync + method + session

i'm having issues with wrapAsync + method + sessions.
How do I implement the WrapAsync correctly?
I want, in a template to know if the user has at least one item created by him. And then define whether or not he can create another item.
Now i'm getting this error:
W20141013-15:04:43.237(-3)? (STDERR) Error: Can't wait without a fiber
But, I could not find Fiber at Documentation. And for implementing this, is it really necessary?
 
On the client side I want something like:
//pagina.js
Template.pagina.helpers{
userHasItem: return Session.get('userHasItem');
}
//pagina.js
Meteor.call('userHasItem', Meteor.userId(), function (error,result) {
Session.set('userHasItem', result);
});
//at server side:
if(Meteor.isServer){
Meteor.startup(function () {
var userHasItemAsync = function (userId) {
setTimeout(function () {
if (Items.findOne({'userId': userId})) {
return true;
} else {
return false;
}
}, 4000);
};
Meteor.methods({
userHasItem: function(userId) {
var userHasItemSync = Meteor.wrapAsync(userHasItemAsync),
result;
try {
userHasItemSync(userId);
console.log(result);
return result;
}catch (e) {
console.log('erreur', e.message);
throw new Meteor.Error(500, e);
}
},
}
});
}
Can't get your error to reproduce based on the existing code.
Still, userHasItemAsync is not available because you've defined it locally in the Meteor.startup function. But the error you should get in this case is userHasItemAsync is undefined.
Also the code you've entered here has multiple errors (i guess you typed it in not copy / pasted from your project): template instead of Template, Template it's defined outside of isClient (probably it's in a file available for the client) etc. Because of that it's hard to reproduce your exact case.
There is no need to call a server method to see if the item exists (assuming you have set up the proper publications/subscriptions), nor any need to call wrapAsync. In fact, what you want to achieve doesn't even require a session. All of the code can be ultimately distilled to this:
Template.pagina.helpers{
userHasItem: return Items.find({ userId: Meteor.userId() }).count() > 0;
}
The cursor returned by Items.find is reactive in itself, so there is no need for using a Session.

meteor, meteor call method returning nothing?

Here is my code in client side
var us_exist=Meteor.call('isUserExists',function(e,r){});
console.log(us_exist)// displaying "undefined" in console
if(us_exist==0)
{
console.log("user not exist")
Meteor.call('updatePosts',this._id,option_data,function(e,r){});
}
else
{
console.log("iser exists");
}
here is my method in server side
isUserExist: function()
{
var u_exist=Polls_Coll.find({question:this.question}, {option1:{$elemMatch:{ids: u_name}}} );
return u_exist.count()
}
It is returning nothing.
When i run it in my browser console it is working fine and displaying result as 0 or 1.
The value of the method is not returned from the call function, but rather passed as an argument for the callback. So you should put your code inside that empty callback you've got.
var self = this;
Meteor.call('isUserExists', function(e, us_exists) {
console.log(us_exist);
if(!us_exist) {
console.log("user not exist")
Meteor.call('updatePosts', self._id, ...);
} else {
console.log("user exists");
}
});
By the way, get a habit of not using == operator in JavaScript. You'll be much happier without it in the long run.

Error: Did not check() all arguments during call to '/collection/update'

Meteor throws following exception on the server when I try to do an update on a collection.
Exception while invoking method '/reports/update' Error:
Did not check() all arguments during call to '/reports/update'
The call is simple enough:
Reports.update({ _id : this._id },{ $set : query });
Update:
I tried to add the ´check´ before the update
two versions were tried with the same result: the exception is still thrown
version 1
check(query, Match.Any);
version 2
var update = { $set : query };
check(update, Match.Any);
And the collection has the allow methods defined to allow anything:
Reports.allow({
insert: function(){
return true;
},
update: function(){
return true;
},
remove: function(){
return true;
}
})
Where can I put the check(query, Match.Any) ?
It is spouse to be the same either from an event or a meteor method.
here is an example:
Template.YourTemplateName.events({
"click #yourElement:function(event,template){
check(query,Match.Any);
console.log("working");
//will always log "working"
}
});
"click #yourElement:function(event,template){
check("String",Number);
console.log("Not working");
//will throw an error and will not execute the log
}
});
also you can try Match.test which will return true if the value matches a pattern.
example:
"click #yourElement:function(event,template){
if(Match.test("String",String)){
console.log("working");
//will execute
}
}
});

Resources