Where do I properly put my constants in Meteor - meteor

I usually follow the unofficial Meteor FAQ on how to structure my codebase, but I can't figure out where I should put my global constants.
To give an example: I have some database entries with a constant GUID that I need to reference in many points of my app. So far I just attached the constants to the relevant collection, such that in collections/myCollectionWithGuids.coffee it would say:
#MyCollectionWithGuids = new Meteor.Collection "myCollectionWithGuids"
#MyCollectionWithGuids.CONSTANT_ID = "8e7c2fe3-6644-42ea-b114-df8c5211b842"
This approach worked fine, until I need to use it in the following snippet, located in client/views/myCollectionWithGuidsView.coffee, where it says:
Session.setDefault "selectedOption", MyCollectionWithGuids.CONSTANT_ID
...which is unavailable because the file is being loaded before the Collections are created.
So where should I put my constants then, such that they are always loaded first without hacking in a bunch of subdirectories?

You could rely on the fact that a directory names lib is always treated first when it comes to load order.
So I would probably advise you to organize your code as follow :
lib/collections/collection.js
client/views/view.js
In your particular use case this is going to be okay, but you might find cases when you have to use lib in your client directory as well and as the load order rules stack (subdirectories being loaded first), it will be loaded BEFORE the lib folder residing in your project root.
For the moment, the only way to have full control over the load order is to rely on the package API, so you would have to make your piece of code a local package of your app (living in the packages directory of your project root).
It makes sense because you seem to have a collection and a view somehow related, plus splicing your project into a bunch of collaborative local packages tends to be an elegant design pattern after all.
Creating a local package is really easy now that Meteor 0.9 provide documentation for the package.js API.
http://docs.meteor.com/#packagejs

I would put your collection definitions in a lib directory. File structure documentation explains that all files under the lib directory get loaded before any other files, which means your variable would be defined when you attempt to access it in your client-side code.
Generally speaking, you always want your collections to be defined before anything else in your application is loaded or executed, since your application will most likely heavily depend upon the use of the collection's cursor.

Related

How do you get code used on both the client and the server to load before all code in server/ and client/ folders?

I have some code that is used on both the client and the server, that I need to be loaded before all code in server/ and client/
I tried to put the common code in lib/, but then I run into issues when I have code in client/lib and server/lib that depends on the code in lib/ to be defined when they load.
Here's an example of file load order from the Meteor documentation under the section File Load Order:
nav.html
main.html
client/lib/methods.js
client/lib/styles.js
lib/feature/styles.js
lib/collections.js
client/feature-y.js
feature-x.js
client/main.js
According to this example, files in client/lib/ get loaded before files in lib/.
I need the files in lib/ to load before the files in client/lib/. Is there any way to change this?
I'm putting my collection definitions in lib/, and my client subscriptions in client/lib. Organizing it like this makes sense to me because, my helpers in client/helpers.js depend on client/lib/subscriptions.js, and my subscriptions depend on the collections defined in lib/collections.js, and both the client and the server need the collection definitions, so I put them in lib/.
I found a clever solution.
I essentially renamed ./client/lib/ to ./client/deps/, which changed the load order to the following.
./lib/collections.js
./client/deps/subscriptions.js
./client/helpers.js
I need this order because my subscriptions depend on a collection being defined, and my helpers depend on subscriptions being defined.
The folder ./client/lib/ will always be loaded before ./lib/, but ./client/deps/ will be loaded after ./lib/ and before ./client/helpers.js, because ./client/deps/ is a deeper folder than ./client/, as per the Meteor documentation on File Load Order.

How does DllImport in ASP.Net look for the DLL?

Is it documented somewhere how ASP.Net sets up search paths for native DLLs? I need to be able to replicate the logic in my own code.
For more background: I'm maintaining a managed library (say Managed.DLL) that wraps a native library (say Native.DLL) that in turn uses another native DLL (say Driver.DLL). So far Managed.DLL has been importing functions from Native.DLL using .Net's DllImport attribute, but now I have to change this to hand-coded calls to LoadLibrary and GetProcAddress to get more control; in particular, I need to be able to call FreeLibrary to unload Native.DLL and I can't do this when Native.DLL has been loaded via DllImport.
And here comes the problem: While just DllImport("Native.DLL") is sufficient to locate both Native.DLL and Driver.DLL, calling LoadLibrary("Native.DLL") fails with ERROR_FILE_NOT_FOUND when Managed.DLL is used in an ASP.Net application, because the directory containing Managed.DLL is not on the search path for native code DLLs.
My first thought was to use Assembly.GetExecutingAssembly().Location and then issue the LoadLibrary call with a full path, but then Native.DLL fails to find Driver.DLL, because the directory containing them both is still not on the search path.
I could work around this by using the Assembly.GetExecutingAssembly().Location value to set the native DLL search path with SetDllDirectory, but this has two major drawbacks:
1) SetDllDirectory changes global WinAPI settings and could interfere with other code within the same ASP.Net worker process that also uses native code DLLs; I have also verified that using DllImport attribute does not mess with this setting, so changing it now could indeed break something that was working before.
2) It would still not work for debugging ASP.Net applications from within Visual Studio, because VS copies the managed resources into a temporary directory, but leaves the native DLLs in the project build directory, so they end up in different locations in the debugging session (and the temporary directory is wiped for every debugging session, so copying the native DLLs into it manually does not work either; I had to copy the native DLLs into IIS's directory for the debugging session to find them and this is clearly not acceptable solution).
I really would like to do the compatible thing here, but so far haven't been able to find out what this is and after couple of days of fruitless searches any pointers would be greatly appreciated.
To answer my own question:
1) The keyword I was missing regarding the copying of Managed.DLL was "shadow copying" (James Schubert explains it much better than any official Microsoft documentation I've seen) and the trick is to use Assembly.CodeBase instead of Assembly.Location, because the former gives the the original location of Managed.DLL and the latter the location of the shadow copy (John Sibly and Sneal shared nice code snippets to extract the directory name from the URI in Assembly.CodeBase).
2) The way to make dependencies of the native DLLs available is to explicitly load them using LoadLibrary before they are needed (and since this increments their reference counts, also release them with FreeLibrary when done).
So, the loading sequence is
string dir = Assembly.GetExecutingAssembly().CodeBase;
dir = new Uri(dir).LocalPath;
dir = Path.GetDirectoryName(dir);
IntPtr driver = LoadLibrary(dir + Path.DirectorySeparatorChar + "Driver.DLL");
IntPtr managed = LoadLibrary(dir + Path.DirectorySeparatorChar + "Managed.DLL");
and the unloading sequence
FreeLibrary(managed);
FreeLibrary(driver);
(note also the order of LoadLibrary and FreeLibrary calls).

What are some use-cases for Meteor.isClient?

The docs on docs.meteor.com are very lacking for this check. I've seen elsewhere that it is useful for setting up helper functions in a Handlebars (and the new Spacebars?) JS. But where else would a Meteor.isClient check be required?
It's useful whenever you have shared code between the client and the server. For example, the default code that comes with any new meteor project puts all of the javascript into a single file. Template definitions won't work on the server, so they need to be wrapped within a Meteor.isClient check. Of course in a larger project, you can easily separate these sections into their respective /client and /server directories. However, you could still have utility functions, or methods defined in a shared directory. In those cases you may again find that some portions of the code only make sense when executed in one of the two environments.
TL;DR
They are critical for small apps where all of the code exists in a single file. Larger apps tend to use them only for things like meteor methods which can have a single definition but work differently depending on the environment.

Access uniquely-named Maven snapshot using ivysettings.xml in sbt?

I use an ivysettings.xml file to configure the repositories to use for sbt, which uses Ivy.
However, it's not able to download a particular snapshot which uses unique naming (i.e. date-based naming). It only tries the patterns listed explicitly in my ivysettings.xml file (which makes sense), so it can't see the details in maven-metadata.xml which tell it the filename of the snapshot jar to download.
I tried specifying the version explicitly instead of as a snapshot in Build.scala:
"com.jolbox" % "bonecp" % "0.8.1-20131105.191813-1"
(which would be my ideal solution, because then it would be cached in our maven repository and I'd be guaranteed to always use the same snapshot), but this generated the wrong URL (there should be an 0.8.1-SNAPSHOT in there, but of course there isn't):
http://maven/nexus/content/groups/softwaretools-snapshot-group/com/jolbox/bonecp/0.8.1-20131105.191813-1/bonecp-0.8.1-20131105.191813-1.pom
I then tried specifying the URL explicitly using from, but this didn't work.
I then tried using latest.integration as the version, but that didn't correctly identify the latest version - it thought it was 0.8.0-rc1, which is clearly wrong.
Download the dependency manually and add it to the lib directory of the project (create it if necessary); remove it from the Build.scala file.

In Meteor how can I include a js file in another js file server side?

In Meteor is there a way to include a js file in another js file.
Specifically, server side and most importantly at start up.
The use case I am running into is for complicated Meteor.startups where I need to load quite a bit of data to the mongodb into a variety of collections.
In order to have different test scripts I have to have more than one file each with duplicate data.
So, is there anyway to have say a boostrap.js file that calls Meteor.startup and then is able to load different files in order to load up the test data?
Or can this be done in a different way through some kind of object?
By design Meteor will automatically include all the javascript files in the the entire project (except in the public folder) but only segregate them between the server and client.
You could create objects in separate files and just use the functions or objects whenever you please, they should all be available at startup.
Try using my module loader made for use with Meteor. It's very similar to AMD: https://github.com/matb33/meteor-smd

Resources