Vanilla__
Vanilla__

Reputation: 63

How to reactively execute code as soon as a client Collection grows?

I'm trying to keep track of an increment of a certain reactive value in Meteor. If the current value has increased by 1 or more, I want something to happen. I do have two problems:

This is the code I have now, using the Mongo.Collection cars (which is from an API):

api = DDP.connect('url');
const currentCars = new Meteor.Collection('cars', api);
const newCars = cars.find().count()

if (Meteor.isClient) {
  Template.currentCars.helpers({
    carsInCity: function() {
      return currentCars.find(
      {
        location: "city"
      }).count();
    },
  })
}

So there's a current amount of cars in the city. Everytime when there is one more car, I want something to happen in the code. But how on earth can I do that? Maybe by keeping track of when the database has been updated?

Upvotes: 2

Views: 67

Answers (1)

Kyll
Kyll

Reputation: 7151

A fairly straight-forward solution would be to store the current amount of data in that collection, then run a reactive computation to see if anything changed.

Something like this:

let currentCarsCount = cars.find().count()

Tracker.autorun(function checkForAddedCars() {
  // cars.find() is our reactive source
  const newCarsCount = cars.find().count()

  if(newCarsCount > currentCarsCount) {
    currentCarsCount = newCarsCount
    // There's new cars, handle them now
    // ...
  }
})

You may also want to use a template-level autorun so that you don't have to manage stopping checkForAddedCars. You could also store currentCarsCount as a state on the template instance instead of as a hoisted loner.

For example:

Template.currentCars.onCreated(function() {
  const templateInstance = this;
  // equivalent:
  const templateInstance = Template.instance();

  templateInstance.currentCarsCount = cars.find().count();

  templateInstance.autorun(function checkForAddedCars() {
    // cars.find() is our reactive source
    const newCarsCount = cars.find().count();

    if(newCarsCount > templateInstance.currentCarsCount) {
      templateInstance.currentCarsCount = newCarsCount;
      // There's new cars, handle them now
      // ...
    }
  });
});

It would also allow you to access currentCarsCount from other places in the template code.

Upvotes: 3

Related Questions