Zach Zach - 6 months ago 22
Javascript Question

How do you fix file load order problems using Meteor.startup?

Many resources on the internet (including here) suggest using

to fix dependency issues caused by the order in which JS files load. However, nobody spells out exactly how this is accomplished.

Specifically, it seems like file order dependency is the reason I can't get my posts.coffee collection to recognize permissions defined in my permissions.coffee. I think this is happening because posts.coffee is in /lib/collections, whereas permissions.coffee is in /lib, and files in subdirectories get loaded first. (Incidentally, I would prefer /collections to be in the root directory, but I had to move it into /lib previously to solve a similar problem.)

Here is my posts.coffee:

@Posts = new Meteor.Collection('posts')

Posts.allow(
update: ownsDocument
remove: ownsDocument
)

Meteor.methods(
...


And here is my permissions.coffee:

@ownsDocument = (userId, doc)->
doc && doc.userId == userId


(This is all from the "Discover Meteor" book tutorial, by the way, around these commits, except in CoffeeScript.)

My question: Assuming my analysis of the problem is correct, how would you solve it using
Meteor.startup
? This answer is hard for me to interpret; one interpretation is that I should wrap
Posts.allow(...)
in
Meteor.startup
somehow, but that seems really clumsy. Maybe I'm wrong, but it seems like there should be one general/config file with all the necessary startup code, and specific controllers should remain ignorant of it.

BTW, I realize I could hack a solution by taking advantage of Meteor's default file load ordering rules (e.g. /lib first; subdirectories first; main.* last; alphabetically), but that's a really inelegant solution to what should be a simple problem. I don't want to have to append "a" in front of a filename or create spurious directories just to get it load before another file.

One last note: I'm using CoffeeScript, and I wonder if the way CS handles global scope has something to do with it. (E.g., instead of defining my
Posts
collection as a JS variable without the
var
keyword, in CS I have to define is as
@Posts
, which I believe makes it a property of the window.)

Answer

Yes, you do just that:

Meteor.startup ->
  Posts.allow(
    ...
  )

Basically, any piece of code that uses a variable defined in another file should be preceded by Meteor.startup ->, unless you are sure that the loading order is correct (the variable is in lib, for example).

Yes, the loading order is poorly chosen.