Meteor-Community-Packages / meteor-collection-hooks

Meteor Collection Hooks
https://atmospherejs.com/matb33/collection-hooks
MIT License
657 stars 92 forks source link

Can't modify records after.update #186

Closed jasonnmark closed 7 years ago

jasonnmark commented 8 years ago

I'm building creating a field which includes firstName and lastName to use with EasySearch autocomplete. This script works:

Contacts.before.update(function (userId, doc, fieldNames, modifier)  {
    modifier.$set.searchOnMe = doc.firstName + ' ' + doc.lastName;
});

BUT, it writes the old data. For example. If we have a contact named "oldFirstname oldLastname" and change it to "newFirstname" it updates searchOnMe to be the OLD data, not the new data.

It seems to me that the simple solution is to switch it to "after.update" but when I do it doesn't write the data.

I feel like I'm missing something simple, or trying to use a hammer as a screwdriver or something... Any advice would be greatly appreciated.

matb33 commented 8 years ago

Try grabbing firstName and lastName from the modifier instead

jasonnmark commented 8 years ago

How can I extract these values from the modifier? Regex? I'm getting this as a modifier when the firstName is edited: {$set: {firstName: "user entered first name"}} I imagine in some cases I'll get a single value back and in others I'll get an array...

matb33 commented 8 years ago

You should be able to grab it normally, i.e. var firstName = modifier.$set && modifier.$set.firstName;

The update hook gets fired for each updated record

jasonnmark commented 8 years ago

So... close. I added an if statement into the before.update which uses the modifier if it's there and the field content if not, and sets the modifier to "do the right thing" and spits it out in my console log,

{$set: {firstName: "firstname", searchOnMe: "firstname "}}

but as soon as I add this line of code to my before.update script, then it stops updating: if ($.inArray('firstName', fieldNames) > -1){ var firstn = modifier.$set && modifier.$set.firstName

matb33 commented 8 years ago

Did you end up figuring this out, or is there something I should be looking at?

jasonnmark commented 8 years ago

Thanks Matb... I got it working. It's a bit convoluted as I need to test for empty fields, but it works. I would be GREAT if "before update" could smartly process both new data and existing data. For example if someone changes JUST the first name it would be great if it could grab the first name from the form and the last name from the database without explicitly checking both.... but like I said it works and it's logical and it's MUCH easier because of the awesome libraries you've contributed... so thanks. :)

matb33 commented 8 years ago

Hey @jasonnmark, I had a look at the issue you referenced in meteor-easy-search -- you could shorten your code block quite a bit:

Contacts.before.update(function (userId, doc, fieldNames, modifier) {
    modifier.$set = modifier.$set || {};
    modifier.$set.searchOnMe = [
        modifier.$set.firstName || doc.firstName,
        modifier.$set.lastName || doc.lastName
    ].filter(Boolean).join(' ')
})

Just a suggestion

jasonnmark commented 8 years ago

Dude you rock! Thanks so much. I only have a dozen hours of programming experience (other than HTML waaaay back in the day) so these sorts of tips are SUPER helpful. :)

zimme commented 7 years ago

I'm closing this issue as it seems you found a solution.