1

In my project I'm using package which needs collection name to do some search inside collection. I just migrated into Meteor 1.3 and now this package doesn't work.

In the code package use something like:

const search = (collection_name) => {
   let collection = this[collection_name]
   ...
}

Now collection is not in global scope anymore. I could add my collection there doing global[collection_name] = Collection in my lib/collections.js, but I'd rather like to fix package to be more flexible and Meteor 1.3 compatible.

Are there any possibilities how to get Mongo Collection if you know only collection name?

Jaro
  • 982
  • 1
  • 10
  • 25
  • I believe you can do `window[collectionName]`, see http://stackoverflow.com/a/20785981/2805154 – Michel Floyd May 12 '16 at 23:10
  • No, you can't. I mean it will not work on server, that's why I mentioned `global`. In Meteor 1.3 you have to add then into global space manually, which is not good solution. That would force each Meteor 1.3 app creator (who is using my package) to add their Collections into global space manually. And main idea of using ES6 modules is to avoid globals as much as possible. – Jaro May 12 '16 at 23:35

4 Answers4

1

Rather than using what seems to be a private api that may change without notice as suggested by Archimedes, I recommend creating a global object to hold your collections. The meteor docs specifically state:

Generally, you'll assign Mongo.Collection objects in your app to global variables. You can only create one Mongo.Collection object for each underlying Mongo collection.

So if you have a Collections global, you can easily access the collection in question via Collections[name]. Of course you do want to limit your globals, so if you do currently have a global for your application, just give it a property to hold your collections. The following is a common pattern that you can adapt to your needs, whether your collections are located in a single file or seperately.

app = app || {};
app.collections = {
    // collections here
}
sheeldotme
  • 2,237
  • 14
  • 27
  • Unfortunately this solution would not work, because I need it in package and don't want to force other app crested to force using one or other style of how to put collections into global name space. – Jaro May 13 '16 at 12:00
1

Thanks to @sashko recommendation I looked at https://github.com/dburles/mongo-collection-instances and then to lai:collection-extensions and here is how I solved it:

import { CollectionExtensions } from 'meteor/lai:collection-extensions'

let registered_collections = {}
CollectionExtensions.addExtension(function (name, options) {
  registered_collections[name] = {
    name: name,
    instance: this,
    options: options
  };
});

export function getCollectionByName(collecion_name) {
    return registered_collections[collecion_name].instance
}
Jaro
  • 982
  • 1
  • 10
  • 25
0

Use the following technique

Meteor.default_connection._mongo_livedata_collections.users.find({}).fetch()

Just replace users with whatever collection you have.

https://forums.meteor.com/t/es6-global-collection-variables/22392/2?u=trajano

Archimedes Trajano
  • 35,625
  • 19
  • 175
  • 265
  • This returns the underlying collection not the Meteor.Collection, so an insert to this doesn't work properly. I.e. It appears on client but isn't sent to server. – malhal Jun 21 '16 at 06:09
0

Try this magic (in client code):

Meteor.connection._stores['tasks']._getCollection()

For more info checkout:

meteor/meteor#5845 (initial attempt Dec 2015)

meteor/meteor#6160 (fixed Feb 2016)

Or if you prefer public API and don't mind another dependency use mongo-collection-instances as mentioned in the other answer.

malhal
  • 26,330
  • 7
  • 115
  • 133
  • I'm getting `TypeError: Cannot read property '_stores' of undefined` for this :( – Jaro Jun 22 '16 at 12:44
  • Sorry about that, check your Meteor version as this was only just added in Dec 2015, but had to be fixed in Feb 2016, I'll update answer with links. – malhal Jun 22 '16 at 12:45
  • It's Meteor 1.3.3.1 – Jaro Jun 22 '16 at 13:32
  • Oh sorry this is for the client code only it seems. – malhal Jun 22 '16 at 13:43
  • Then this solution isn't good fit. I need something what I can use in methods on server. So my chosen solution with `import { CollectionExtensions } from 'meteor/lai:collection-extensions'` looks like best solution for now. – Jaro Jun 22 '16 at 21:24