samedi 30 mai 2015

How do I publish two random items from a Meteor collection?

I'm making an app where two random things from a collection are displayed to the user. Every time the user refreshes the page or clicks on a button, she would get another random pair of items.

For example, if the collection were of fruits, I'd want something like this:

apple vs banana

peach vs pineapple

banana vs peach

The code below is for the server side and it works except for the fact that the random pair is generated only once. The pair doesn't update until the server is restarted. I understand it is because generate_pair() is only called once. I have tried calling generate_pair() from one of the Meteor.publish functions but it only sometimes works. Other times, I get no items (errors) or only one item.

I don't mind publishing the entire collection and selecting random items from the client side. I just don't want to crash the browser if Items has 30,000 entries.

So to conclude, does anyone have any ideas of how to get two random items from a collection appearing on the client side?

var first_item, second_item;

// This is the best way I could find to get a random item from a Meteor collection
// Every item in Items has a 'random_number' field with a randomly generated number between 0 and 1
var random_item = function() {
  return Items.find({
    random_number: {
      $gt: Math.random()
    }
  }, {
    limit: 1
  });
};

// Generates a pair of items and ensure that they're not duplicates.
var generate_pair = function() {
  first_item = random_item();
  second_item = random_item();

  // Regenerate second item if it is a duplicate
  while (first_item.fetch()[0]._id === second_item.fetch()[0]._id) {
    second_item = random_item();
  }
};

generate_pair();

Meteor.publish('first_item', function() {
  return first_item;
});

// Is this good Meteor style to have two publications doing essentially the same thing?
Meteor.publish('second_item', function() {
  return second_item;
});




Aucun commentaire:

Enregistrer un commentaire