Autumn Leonard
Autumn Leonard

Reputation: 511

In Meteor, how to choose a collection based on a variable?

Let's say you want to dynamically insert into different collections. Right now I am using a switch statement:

switch (i) {
  case "dog":
    Dog.insert({
      name: "Skippy"
    });
    break;
  case "cat":
    Cat.insert({
      name: "Skippy"
    });
    break;
}

But this is messy, and if I need to support future collections, it fails. Is there a way to choose the collection based on "i" in the example above?

Upvotes: 1

Views: 127

Answers (3)

David Weldon
David Weldon

Reputation: 64312

Here's a complete working example:

Posts = new Mongo.Collection('posts');
Comments = new Mongo.Collection('comments');

var capitalize = function(string) {
  return string.charAt(0).toUpperCase() + string.slice(1);
};

var nameToCollection = function(name) {
  // pluralize and capitalize name, then find it on the global object
  // 'post' -> global['Posts'] (server)
  // 'post' -> window['Posts'] (client)
  var root = Meteor.isClient ? window : global;
  return root[capitalize(name) + 's'];
};

var insertSomething = function(name, data) {
  var collection = nameToCollection(name);
  collection.insert(data);
}

Meteor.startup(function() {
  // ensure all old documents are removed
  Posts.remove({});
  Comments.remove({});

  // insert some new documents
  insertSomething('post', {message: 'this a post'});
  insertSomething('comment', {message: 'this a comment'});

  // check that it worked
  console.log(Posts.findOne());
  console.log(Comments.findOne());  
});

Note this is nearly identical to this question but I simplified the answer for more generic use.

Upvotes: 0

soren468
soren468

Reputation: 319

Correct me if I am wrong but I think this is what you are trying to do:

var Dog = {
  insert: function(props) {
    console.log(props);
  }
}

var insertArbitraryDocument = (function(collectionType, props) {
  window[collectionType].insert(props)
}).bind(this);

insertArbitraryDocument('Dog', {name: 'skippy'}); //=> {name: 'skippy'}

In this snippet you are accessing the window object and getting the property of whatever name you are passing in (must be exactly the same as the collection). Then you can call your usual function calls.

Upvotes: 2

Christian Fritz
Christian Fritz

Reputation: 21364

I don't think there is a meteor built-in way of doing this, but it's pretty easy to just create a directory of collections manually:

JS in common to client and server:

var collections = {};

function myColl(name) {
    var coll = new Meteor.Collection(name);
    collections[name] = coll;
    return coll;
}

// and now just use myColl instead of new Meteor.Collection
Dog = myColl('dog');

And then, to do what you want to do:

collections[i].insert(data);

Upvotes: 0

Related Questions