Vulcan icon indicating copy to clipboard operation
Vulcan copied to clipboard

onCreate, onUpdate, etc does not run for nested schemas

Open Apollinaire opened this issue 6 years ago • 5 comments

For the following schema the functions onUpdate and onCreate never run:

const NestedObject = new SimpleSchema({
  nestedField: {
    type: String,
    canRead: ['members'],
    onUpdate: () => 'has been updated',
    onCreate: () => 'has been created',
  }
});

const shema = {
  arrayField: {
    type: Array,
  },
  'arrayField.$': {
    type: NestedObject,
  },
}

I think it would be nice to take care of this. It's quite tricky because it runs inside an Array, so it depends if the Array has items or not. My best option is to run subschema's onCreate, onUpdate, onDelete once for each items. That means if the Array contains nothing, the function won't run. SimpleSchema is supporting this, might be worth looking what choice they made for this.

Apollinaire avatar Jan 09 '19 09:01 Apollinaire

That does seem a little tricky. Currently onCreate/onUpdate/etc. run completely outside of SimpleSchema, but maybe there's a way to "integrate" them into the SS validation? Assuming SS has equivalent callbacks.

If not then we need to write a more advanced callback-triggering function that recursively traverses an object. Shouldn't be that hard, but it does sound like something that could easily create more bugs in the future…

SachaG avatar Jan 09 '19 09:01 SachaG

I was not suggesting to go through SimpleSchema for this, simply to look at how they are running their validation. I think they must have the recursive thing. For now I would check if subschemas have an onCreate, onUpdate, onDelete and run it in a loop of its own (not with SimpleSchema). I agree that creating something more complicated might lead to bugs or unexpected behaviours.

Apollinaire avatar Jan 09 '19 13:01 Apollinaire

We could reuse the forEachDocumentField, I've used it to implement permission check and dates conversion. It's not perfect but at least it can either be reused directly or at least serve as an inspiration.

The onCreate function could use the same code, what we lack is more the expected behaviour when 2 callbacks might create/update the same field.

For example it could be 1. running the parent onCreate 2. running the children onCreate. So a nested array would be generated using its onCreate function. Then we iterate on the array to run children onCreate function. If the result is ambiguous it's user responsibility, at least the behaviour would be predictible and easy to figure.

eric-burel avatar Feb 17 '20 18:02 eric-burel

Example schema that worked previously: https://github.com/GraemeFulton/letter-modules/tree/1.13.0/letters/sub-schemas https://github.com/GraemeFulton/letter-modules/blob/1.13.0/letters/schema.js

eric-burel avatar Feb 17 '20 18:02 eric-burel

Also for array, when we add an item, we can be in an update mutation, while new items might want to run their onCreate function.

eric-burel avatar Mar 10 '20 15:03 eric-burel