What are some use-cases for Meteor.isClient? - meteor

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.

Related

Multiple public directories in Meteor?

In meteor, I can have multiple client, multiple server directories, etc. (ex: /foo/client/ and /bar/client/) I segment my app by behavior, for example /users/* for user management, subs, methods, UI, etc., or /inv/* for inventory management, collections, subs, methods, UI, etc., and all other parts of my app. This allow some code organisation and separate components and methods so the app will scale better in the long term.
This works quite well so far, however I need to add some assets to each segments of the app and, since the /public directory content is copied over /.meteor/.local/build/programs/web.browser/app, I wanted to know if it was possible to have multiple public directories, where all files would be merged into the build target?
No it isn't currently possible to have multiple public directories within a single application. This is disallowed by Meteor's Isobuild system. If you want to maintain separate /public directories with related component functionality, then you should look into leveraging Meteor packages. Packages can have their own public assets. The "Building Large Apps: Tips" hackpad talks about how you can leverage a "packages-for-everything" approach with Meteor and achieve the type of component separation (with separate public assets) you're looking for. That being said most of the Meteor community has either moved, or is starting to move, away from a "packages-for-everything" approach. The launch of Meteor 1.3 and ES2015 module support has made this approach mostly unnecessary (with a few exceptions, like maintaining separate public assets).

Where to place non-app assets in a Meteor project to avoid bundling?

Per the Meteor docs, I'm trying to determine which special folder to place non-app assets (ex. Photoshop design PSDs) in, so that they still get checked into source control but don't get wrapped into the eventual client or server payloads.
It feels 'wrong' to use tests/ for this purpose but the docs suggest it has the desired behavior. Can private/ be used similarly, or will its contents always get added to the server bundle regardless of whether your app code registers any Assets? (Or is there a better place altogether to put such files?)
Consider a project structure like this:
/YourMeteorProject
/YourPSDFiles
file1.psd
file2.psd
...
/YourMeteorApp
/.meteor
/client
/server
...
You can launch your meteor app from within /YourMeteorApp. Files that are not part of your application, such as your PSD files, are kept outside of the application.

Where do I properly put my constants in 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.

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

Clarification on web2py apps sharing a single database

Sorry, I'm a little unclear on the web2py manual explanation.
as an example, given app1 and app2
I want to have app2 share the database I have built in app1
So do I change the app2/models/db.py file to show: db = DAL('sqlite://storage.sqlite',migrate='false') ?
and include all other myModel.py files in app2/models directory as well?
if the database is in app1/databases/ how does app2 know how to find the correct database file?
This Thread begins to answer the question but I'm still unclear on how to define where the shared database lives.
Note, DAL(..., migrate=False) just sets the default value of migrate for each table -- it will not have any effect on the migration status of tables whose define_table() calls include their own explicit migrate argument. If you want to completely disable migrations for an entire db connection (regardless of the individual define_table() calls), instead use:
DAL(..., migrate_enabled=False)
Also, to share model definitions between applications, rather than simply copying the model files, you could put the definitions in functions or classes within modules and then import the modules. Another option is to use auto_import:
DAL(..., auto_import=True)
Note, auto_import will import the field names and types, but it will not include DAL-specific attributes, such as validators and defaults, so its usage is somewhat limited.
I can't test this right now but the answer should be:
you can override the folder in the DAL:
So both apps should point to the same file.
(see the docs and this thread).
.
db = DAL('sqlite://storage.sqlite',folder='path/to/app/databases')
yes, should need the model files in both apps too, otherwise the apps won't know how to access the db.

Resources