Refactoring Meteor code


#1

I have some trouble refactoring some of my code and also some trouble of putting some code blocks in their intended wrappers(isClient or isServer). So i’ll use this thread to put my questions about those issues.


#2

I have a main js file that (among other things) defines a collection and in isServer I publishes it to the client.

var Collection = new Mongo.Collection('collection')

if (Meteor.isServer) {

	Meteor.publish("collection", function () {
   
    	return Collection.find();

  });


}

But when i try to access that collection in another file by:

if (Meteor.isClient) {

	Meteor.subscribe("collection");
	console.log(Collection.find());
}

I get an error of Collection not defined.

edit: I tried putting the main.js in the lib folder so that it gets executed first but it didn’t work


#3

The “var” keyword makes the variable local to the current file. Remove it to make it global.


#4

I’m still getting the console error that the collection it’s not defined


#5

both files are in the client, but surely the error is in the file that defines Collection is charging after the other file and therefore is not defined


#6

But shouldn’t the file that’s in the lib folder run first? Or should I put that file somewhere else?
The other file that calls the console log is currently in the root directory, could that be the issue?

edit: I forgot to say I have no issues calling Meteor.userId() in that file but when I call Meteor.user() I get undefined. Not sure how is this possible

edit2: had to refresh a few times to get Meteor.user()


#7

Hi chos89,

Meteor.user() will resolve to null initially because the client hasn’t asked the server to log in yet. You always need to check whether the user is available before using it (eg. with if (Meteor.user()) { /* run code depending on the user being there */ }


#8

I see, thanks.

How do you guys organize your code so that this works.
Where do you put the file that defines a collection and an other that uses it?
I have a feeling I’m missing something elementary here, I have to say I’ve been programming for 3 months and maybe I’m overlooking something that would be obvious for you guys so think in a way this guy is retarded :smile:


#9

So, I’ve tried running my planned code and it worked?!

When I run return Collection.find(some filters) in template.xxxx.helpers I get the data but when I console log it it doesn’t return anything. Is this a bug or am I missing something obvious.


#10

Bonus questions in this monolog:

  1. if the helper method cant find anything in the collection matching the query does it return a null as in false or an empty array

Point is, would this work:

{{#if helperMethod}}

//show if has any

{{else}}

//show this if no match

{{/if}}

Or do I need to check the length myself and return true or false?

2.How does one console log a helper method

a) (Template.mytemplate.helperMethod)
or
b) (Template.mytemplate.helpers.helperMethod)


#11

I usualy used something like that to check for empty collections:

{{#if collection.count}}
    {{#each collection}}
        ... Do something
    {{/each}}
{{else}}
    ... No match, print empty collection message
{{/if}}

The same works with collection.length if you are iterating on an array instead of a cursor (ie. you used collection.find.fetch()).


#12

Thanks, .count worked, I tried .length but i didn’t know i had to use .fetch() for that, still getting my head around cursors.

Anyone knows answer to the bonus question 2? Because i’m still getting Collection undefined error but Blaze is able to render the data from the helper so this could be a bug since i’m on windows. Thanks.


#13

collection.find() returns a Cursor which has a count method and is reactive. If you use fetch on a cursor, you get a non reactive array.

Template helpers are stored in Template.mytemplate.__helpers if you want to call them for debug purpose, not sure if this is what your are looking though.


#14
{{#each collection}}
    ... Do something
{{else}}
... No match, print empty collection message
{{/each}}

#15

Then

console.log(Template.someTemplate.helpers.templateHelper)

should return the same value that is rendered on the page via

Template.someTemplate.helpers({
	  templateHelper: function () {
	    return Collection.find({createdBy: Meteor.userId()}, {sort: {date: -1}});
		}
	  
	});

Because I’m geting undefined and yet the data is showing on the page, at this point im more interested if this is a bug because I’ve got my data displayed and I want to know should I continue to debug this way or not.


#16

Didn’t know this works, thanks :wink:


#17
{{#with value}}
    ... Do something
{{else}}
... No match, print empty collection message
{{/with}}

Works to


#18

How would you guys do this.
I have this peace of code(simplifed here) in my client

Template.register.events({

"submit form" : function() {
    
  register var's and stuff... 

 Accounts.createUser({}, function(){

   if(true) {
    
     Accounts.sendVerificationEmail(userId);

}}

The issue is in the sendVerificationEmail method that according to the docs should be on the server but my register event is on the client, do I need to somehow call it on the server since this is probably not safe or something?


#19

Any good tutorials on creating and validating users?
Or some public github app where I could look into it to see how it’s done there.


#20

Good tutorials? Not sure but start here: https://atmospherejs.com/useraccounts.