@mordrax, @babrahams: That’s right, I did use Blaze.registerHelper (well , Template.registerHelper, specifically, but I suppose it’s the same thing (no?)), and I was trying to access it from a template helper, unsuccessfully.
Global variables are a thing with meteor. As are Sessions. If you do a search, you'll find alot of information on these two topics because it's a bit of an anti-convention but if you start using non-globals, you start to go down a rabbit hole of how do I reference this particular scope when I'm in that place. The problem with templates is that there is alot of scopes. Each template and nested template has it's own scope, IR functions have their own, hooks and helper functions have their own, events as well. And between all this, there isn't a good way for them to talk to each other. I've been at meteor for 2 months? and about half of that is trying to figure out scope which isn't nice... angular was alot nicer in this respect.
I hear what you’re saying. I’m new to Meteor also (about three weeks in), and while I really (really) like it, I am finding the hardest thing to wrap my head around is the scope landscape. It seems like there are a lot of “gotchas” (so to speak) in terms of scope that aren’t obvious to a Meteor beginner, but that you must learn about as you go.
I hear what you’re saying about the convenience of global variables. But I agree with the philosophy that advocates avoiding pollution of the global scope with a lot of global variables. And, that’s not to say I believe they should never be used - definitely, there are times when they are appropriate, or even the only logical option, in certain circumstances.
With that said, this is my first time (with Meteor) in using JavaScript on the server. All of my experience with JavaScript is from front-end development with various frameworks, and I think the philosophy of avoiding global scope pollution with a bunch of global variables grew out of the nature of JavaScript on the client, where the global scope is the browser’s window
object. If all the framework authors were heavily dependent on using the global scope for variables, there would have been a lot of naming collisions.
So, I’m not sure how big of a problem it is on the server. In fact, I’m not even sure what takes the place of the window
object at the global scope level on the server. Maybe it’s not an issue.
But since I’m kind of in the habit of avoiding putting new variables in the global scope whenever possible, maybe the best solution for simple variables you need access to globally (in templates, template helpers, and other scripts in Meteor) is to put them in Minimongo on the client, or Mongo on the server, or some other type of datastore.
For functions you want to have access to from everywhere throughout your app, I’m not sure. I thought, from reading the docs and Discover Meteor, based on the special directory names and the official file loading order, the best place to put functions that should be accessible everywhere was in a directory named lib
(at any level within your app’s directory hierarchy).
So, anyway, I moved the urlHasProtocol()
function to a new file, /lib/validators.js
, and re-defined it as an anonymous function: i.e. var urlHasProtocol = function() { ... }
. At first when I moved it to that file, it was defined as a non-anonymous, normal function (i.e. function urlHasProtocol() { ... }
), but Meteor complained that it was undefined:
Uncaught ReferenceError: urlHasProtocol is not defined
That was odd, I thought also. I’m not sure why it couldn’t find it when it was defined as a named, non-anonymous function. But it works as an anonymous function, so I’m happy with that.
Maybe the Meteor developers would like to weigh in on the best place to put (and the best way to define) functions that need to be accessible in every scope, on the client as well as the server? Is the lib directory a good place for that? Is it correct that such functions must be defined anonymously and assigned to a variable?
Thanks