[SOLVED] How to check within a package whether some other package has been loaded?

Let’s say I have a package C and I want to call some method from package A OR B based on the fact which one has been loaded. My package DOES NOT import neither package A nor B but they may or may not be imported with some other package.

For example, I want to check whether either Iron.Router or FlowRouter has been loaded and act accordingly, for example - add a new route.

Also, I need to call certain methods BEFORE the page loads (Meteor.startup() is too late).

Ideally, I’d like to do that check right upon all packages have been loaded but before any rendering has been started.

The build system works well to tackle that issue :

  • the packages will be placed before your custom code, so you don’t worry about it
  • packages are defined with “api.use” methods, so if you have “api.use(‘underscore’, ‘client’);” in your package, it will require underscore to be placed before itself. You don’t need to import them, juste “use” them and you can “use” iron router.

The notion of “loading” is not really appropriate. You load all your scripts once in the beginning. This is not a require js like system. So the only thing that matter is the order of modules declaration.

Thanks Fabien,

As I stated in my description, I don’t want to api.use() packages A or B by myself (my package); what I want is to check whether they’re api.use()d by any other package, and if any of them (usually one inherently excludes others, like in my example - Iron.Router vs. FlowRouter), I want to call certain methods in them, depending on the package in question.

Furthermore, I want to call those methods within my package, not within ‘custom’ (app) code. For example, I want to call Router.route('/myroute', {name: 'myroute', template: 'MyRoute'}); only if Iron.Router is being used, but if FlowRouter is used I want to call a slightly different method (not really in this particular example but you get the picture :wink: ) thus adding new route to the application regardless of the type of the router used.

You need to weakly depend on those packages (see http://docs.meteor.com/#/full/pack_use). The documentation for the weak option explains it quiet well.

How about checking for the packages in your package code?

if (Package['iron:router']) {
  // Iron Router stuff
} else if (Package['kadira:flow-router']) {
  // Flow Router stuff
}

… and use the weak option like Sanjo already pointed out.

Thanks guys,

That did the trick:

In my package.js:

api.use([
  'iron:router',
  'kadira:flow-router'
], [ 'server', 'client' ], {
  weak: true
});

In my package code:

var router;

if ( Package[ 'iron:router' ] ) {
  router = Package[ 'iron:router' ].Router;
} else if ( Package[ 'kadira:flow-router' ] ) {
  router = Package[ 'kadira:flow-router' ].FlowRouter;
}

router.route( '/myroute', {
  name    : 'myroute',
  template: 'MyRoute'
});