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

@jkuester, since this was brought up on another topic, I just thought I ask if there is a possibility to release Meteor 3.0 compatibility into 2 steps

Step 1: Meteor 3.0 compatible - sync functions remain sync

This means that those who don’t use async computations can use this for Meteor 3. This is also an opportunity to those with simple async computations to decide to just move the code elsewhere.

Step 2: Make full-async

1 Like

@rjdavid I made a 3.0 branch that should already cover step 1 but I don’t remember if this was just an RC or already a new full release. Let me check and get back to you later. Again - step 1 should already work in terms of code

2 Likes

Sorry I posted this in the other topic, the stage 1 is covered by 2.0.0-rc.0.

2 Likes

Coming back to this I did another analysis again an I might be able to do a dual solution that has validate and validateAsync.

Either way requires a bigger decoupling of the computations from the validation in terms of code plus may loose Tracker functionality in the async version but it would at least remain in the sync version, at least from what I have seen from the Blaze async implementations.

2 Likes

It’ll be really cool if we can keep both of them!

Wouldn’t this be really bad? I’m not sure I fully understand what we’d be losing here. Could you explain more?

The computed properties and labels are currently sync but use Tracker, if in use. Similar Blaze this would not work 1:1 reactive with the async counterparts. In Blaze this has been implemented by @radekmie using a workaround but it still affects many codebases. I am at this point not sure if this will work the same way for SimpleSchema. Affected packages would be Autoform but I will need some more time to confirm this.

1 Like