I have a Meteor collection, and following the meteor docs I’ve made models on the client for the collection documents as they are loaded
Animal = function (doc) {
_.extend(this, doc);
};
_.extend(Animal.prototype, {
feverCallback: function () {
console.log('this animal has a fever !');
}
});
Animals = new Mongo.Collection("Animals", {
transform: function (doc) { return new Animal(doc); }
});
myAnimal = Animals.findOne(); // e.g. { _id : 'foo', temperature : 95 }
I want myAnimal.feverCallback to run whenever myAnimal.temperature jumps over 100… by that i mean another user changes myAnimal’s temperature to 101 for example.
what is the ‘right/best/meteor’ way to set this up ? Collection hooks ? Some kind of Tracker.autorun ? Some kind of query.observe ?
I don’t think you need reactivity to do that.
You could simply put a check in the temperature setter and run the callback when the temperature get over 100.
However, the point of reactivity is to get rid of callbacks.
You could transform you model into a reactive data source.
In the constructor you create a dependency :
this.highTempDep = new Tracker.dependency();
In the setter you do you check and notify if themp is beyond your thresold point:
Thanks @vjau - your idea would work fine if i wanted to capture changes to temperature made by me, but it wouldn’t pick up changes made by other users i think.
I’m pretty sure i have to use observeChanges api to get what i need…
So you can do it like that, with you defined callback :
Tracker.autorun(function(){
var myAnimal = Animals.findOne();
if (myAnimal && myAnimal.temp > 100){
callBack();
};
});
That’s one of the way to do it, but there are many others.
I you give us more information about what your callback is doing, we could probably provide you with a more meteorish way.
at any time, I might have 20, 30, 50… instances of Animal on a given client, each one needs to be able to monitor its own temperature and run a callback if e.g. temperature > 100
Ideally, following the Template pattern, I would love to be able to do something like this
Animal = function (doc) {
var self = this;
_.extend(self, doc);
self.autorun(function(){
if(self.temperature > 100){
self.feverCallback();
}
};
where the autorun would be invalidated when temperature changes, and it would be destroyed when the instance is destroyed.
But at the moment I have to deal with (1) self.temperature is not reactive, and (2) I’m pretty sure my autorun will not get destroyed with the model instance.
When I think of ‘reactivity’, I think I should have a model and I should be able to ask it ‘do you have a fever ?’, and he should tell me reactively true or false. By that I mean I should be able to couple a template to this model and just have a helper
In the past, i have tried to implement “traditionnal” OO patterns with Meteor.
When you are implementing a real domain model with pools of objects, it doesn’t play well with meteor reactivity.
You end up fighting against the framework and getting cache invalidating problems, which Meteor aims to solve.
The way shown by Shock is the real meteor way of doing things.
However with very complex apps, the impossibility to use traditionnal oo patterns (a real domain model instead of what Martin Fowler calls “transaction scripts”), could be the limitation of the framework.
We have still to discover lot of patterns to build complex apps with Meteor.