Simple Schema and Async Support

Here we go again with SimpleSchema. It’s a rabbit hole but that’s the way things are sometimes. So here we go:

I currently migrate SimpleSchema to 3.0. Many props of SimpleSchema fields are computable:

const propsThatCanBeFunction = [
  'allowedValues',
  'exclusiveMax',
  'exclusiveMin',
  'label',
  'max',
  'maxCount',
  'min',
  'minCount',
  'optional',
  'regEx',
  'skipRegExCheckForEmptyStrings',
];

This means you assign a function that returns a value instead of the value itself. You could do something like

{
  foo: {
     type: String,
     optional: () => {
       const userId = Meteor.userId()
       return Roles.userIsInRole(userId, 'canSkipThings')
     }
  }
}

If any of these computations involve a MongoDB call then they will not work anymore as they are all sync.

However it’s currently not possible to implement the validation adaptive to async, so it would support sync AND async. It’s just too much relying on synchonous code that a conditional async would lead to a running bug-carrousel :carousel_horse: :bug:

So my decision is very likely to make the whole SimpleSchema API fully async. I don’t see any benefit of putting even more hours into this to find a solution that works for everybody without breaking things.

Therefore, please expect breaking changes with this package that may bubble up to other packages (Collection2, AutoForm etc.)

Related: Meteor 3.0 compatibility by jankapunkt · Pull Request #741 · Meteor-Community-Packages/meteor-simple-schema · GitHub

Edit: it may read as if I will drop the work on this, this is not the case, I just need to come to a decision how to move on as there are other packages pressuring to be updated as well :rocket:

3 Likes

It’s ok to work towards making it async compliant for the time being and when it’s all good you can put effort into making it working with sync again.

Does this mean it is possible to make all custom function checks to run in parallel using Promise.allSettled() to speed up the checking?

I’m not sure if I understand how you intend to do this. Can you give me a short code example how this could optimally look like?maybe I can then give you an estimation

The idea is that if there are multiple custom async functions, we can get an array of the returned promises and execute all promises concurrently using Promise.allSettled(). The validations will run concurrently instead of one custom function at a time.

I just checked your fork of SimpleSchema and seems like you are now stopping the validations on first error.

The UX for such validations will be bad because it cannot display multiple errors to the user at the same time. Imagine a long form wherein the user has to fix 3 fields (that user has to scroll through the long form and submit the form at least 4 times).

Also, that is no longer compatible to ValidatedMethod that accepts an array of ValidationError

2 Likes

Yeah that’s a good point! I will consider this and also remove the .some logic as it makes no sense to have an array for multiple errors but at the same time stop at the first occurrence!

3 Likes