Open gwendall opened 9 years ago
Might help consolidate the logic for this if hooks were integrated into core (#92 and meteor/meteor#395).
I'm running into this one right now, I (try to) use the before.update hook to calculate some computed fields on the doc. But since there are quite some dependencies on the calculation on different fields in either the doc or the modifier (depending on which one is set and which one will be overridden by the modifier) it's a bit of a headache.
Did someone manage to find a smarter solution than what I'm currently thinking of which is a whole bunch of "if this then that or else use modifier if set" kind of code?
@bensmeets Thinking about it now, you could do that through a dummy collection, ie:
TempCollection = new Mongo.Collection("temp");
var simulateDoc = function(doc, modifier) {
TempCollection.insert(doc);
var selector = { _id: doc._id };
TempCollection.update(selector, modifier);
var simulation = TempCollection.findOne(selector);
TempCollection.remove(selector);
return simulation;
}
I agree it would be helpful. Have any of you tried just leveraging LocalCollection._modify
directly? Something like:
coll.before.update(function (userId, doc, fieldNames, modifier, options) {
LocalCollection._modify(doc, modifier);
// doc should be simulated (I think)... do some logic
});
It would be good to try this in the wild for a bit to get a feel for it.
@gwendall Quite the creative solution :+1:
@matb33 Tried but I can't seem to find how to call _modify. Both through LocalCollection._modify as through MyCollectionName._modify I get an method undefined error. Do you happen to know how to call it?
I've got "some" sort of access to "_modify" in the client through
Package.minimongo.LocalCollection._modify
Callable, but it returns undefined in the server. Checked, the function does exist on the server, but for now still returns undefined.
What you need to do is find a way to use minimongo on the server. I'll be honest... I don't remember how to do this without packages. My meteor projects are all made up entirely of packages, no client
or server
etc folders... so for me it's easy, I just api.use("minimongo", ["server", "client"]);
from whichever of my app packages would need access to LocalCollection
.
Whatever the equivalent would be for non-all-package projects, that's what you're looking for.
I couldn't get it exactly right, but I'm using a variation of @gwendall 's code. Like this:
simulateDocumentModifier: function (doc, modifier) {
var c = new Package.minimongo.LocalCollection('simulations');
c.insert(doc);
var sel = {
_id: doc._id
};
c.update(sel, modifier);
var sim = c.findOne(sel);
c.remove(sel);
return sim;
}
But the effect is a bit opaque. Just hoping I'm not creating a lot of overhead or database collections with it. It works though :)
If using LocalCollection._modify(doc, modifier);
as I mentioned actually does work, perhaps I could have the collection-hooks package use the minimongo package on both server and client, and offer a CollectionHooks.modify
or something like that which just wraps LocalCollection._modify(doc, modifier);
I'm hoping someone can confirm that using LocalCollection._modify(doc, modifier);
does what we would need it to do.
Yep, depending on minimongo
(serverside included) and using LocalCollection._modify works great. It's not publicly documented Meteor API, so took a while for me to find it. You might not even need to wrap it. In the before.update and before.upsert hooks, maybe you can just have oldDoc and newDoc parameters? But, documenting the use of modify function would also work.
Worked for me as well, as long as the minimongo dependency is there for both client and server, this solution works very well.
Hello, LocalCollection._modify works super fine for me !
I think it could be a good thing if " LocalCollection._modify " was on the README as a tip to get the result doc in updates.
I'll look into wrapping LocalCollection._modify
and attaching it to this
inside the hooks.
Hi there!
Has there been any development or "official" support for this now? It would indeed be way easier to fire the proper hooks if we could diff between current and to-be-updated document. I'm just starting to integrate collection hooks in my app, and this is the most difficult thing for me so far.
Is the proposed LocalCollection._modify
still relevant and working (since this thread dates a little...)?
Thanks all for the nice library though.
This is still needed, any news? :)
It would be handy to be able to simulate (using the initial doc + the modifier) what the doc after update would look like. It would make things like security checks pretty easy - right now we have to check $set, $addToSet, etc attributes manually to control what fields are about to get updated. Is there anything on the roadmap for that? If not that would not be too hard, just patching what was done on minimongo. (https://github.com/meteor/meteor/blob/07b6a2245a1e091830844881e7376c38adda3592/packages/minimongo/modify.js)