Simple schema runs validations synchronously, but some validations require server roundtrips or other async calls.
For example, I may want to check a given input if it conforms to some security related constraints or uniqueness constraints etc. And the only way to do that may be to use a server side method. And if it does not, I would like to show an error message to the user.
For such cases, simple schema allows manually adding validation errors
Currently, uniforms only provides the doc to onSubmit callback so there is no way to access the current validation context of the simple schema.
So, it would be great if onSubmit callback had access to the simple schema validation context. In fact, there may be other valuable information that can be provided. So, it would even be better if we had a way to access the whole autoform context in there, not just the document.
For such a validation you can pass an error prop to form. Provided error should be compatible with your schema (ValidationError for SimpleSchema). Also, onSubmit is designed to be a final action.
Could you give an example of a situation, where you would use the whole form's context?
Hmm, do you mean something like:
const PostSchema = new SimpleSchema({
title: {type: String},
body: {type: String}
})
class AddPost extends Component {
constructor(props) {
super(props)
this.state={
asyncErrors: null
}
}
submitPost(doc) {
PostSchema.clean(doc)
Meteor.call('checkIfPostTitleIsUnique', doc, (err,res) => {
if (err) {
this.setState({
asyncErrors: new ValidationError([{name: 'title', type: 'notUnique'}])
})
}
})
}
render {
return <AutoForm schema={PostSchema}
error={this.state.asyncErrors}
onSubmit={doc => this.submitPost(doc)} />
}
}
Does this override the form errors or does it get combined with existing errors?
And what do you mean by onSubmit being a final action? In that case, how do you propose we do asynchronous type checks and validatinons?
I can't give you an answer right now about why I might need the form context, but obviously, aldeed:autoform provides necessary mechanisms and also hooks that give you full access to the form before, during and after its submission. And there may be cases such flexibility is valuble.
Edit:
I think a way to access the form's instance or at least the "simple schema validation context" it creates, is very important. That way, we can even define async validations within the schema itself!
Your example is 100% correct (okay, there's one thing - AutoForm by default calls .clean() automatically). Current error is either the one from props or the one from validation. By the _final action_, I meant onSubmit to have no callback for the user - form calls onSubmit and that's all.
Ok, so I have two follow up questions:
Thanks!
Ok, fair enough. I'll continue manually cleaning after my onSubmit then.
I'm also looking forward to your take on item 2.
It looks awesome! Thank you!
Quick question, as far as I understand, if we provide an error to the callback, then the provided error replaces any existing errors, right? It does not "merge" the errors?
So for example, if the schema validation has error on fieldA and myapi provides error for fielfB and if I pass the error from fieldB to the callback, the form only displays the error for fieldB and it "ignores" the other error, right?
Because my intention was somehow to be able to "merge" all errors together.
Or did I miss something?
You have to merge it by yourself - uniforms API don't know, what exactly the error is - you can easily create a Bridge with a numeric error. If you are using SimpleSchema, you are using ValidationError - that case is simple:
new ValidationError(error.details.concat([{name: 'field', type: 'asyncError'}]))
Yep, this is what I thought and in fact, putting some more thought into it, I like this better due to its flexibility. It is up to the developer to decide what to do with multiple error sources.
Exactly.
@radekmie I think this has created a regression. Now the validation is constantly running and interestingly logging warnings in the console and moving the text cursor to the end of the input!
For example try entering text into the middle of an existing input that does not pass validation

notice also the logs! I'm not logging this and interestingly, I have not even submitted the form and it is not autosave either.
@radekmie I confirm that this is a regression. Reverting back to 12 fixes the problem.
Okay, I'll try to investigate it, but I think it's not exactly that commit, but some of the others between 12 and 13. You could try to do git bisect or something if you want.
I tried to do git bisect but I don't have a testing workflow.
I tried to set up a new meteor project, clone uniforms to an external folder and cd into packages/uniforms and tried to run npm pack so that I can use a local npm package for testing but npm throws me all kinds of errors and nothing useful.
I wonder how you are running your local test setup.
This is in fact quite important because I'll also be working on the examples and docs site so I need to be able to use uniforms from local (to write examples for unpublished versions) instead of from npm.
How do you do that?
In a quite hacky way - I have a meteor project with package.json with an absolute path to these packages on my disk (also, you can try npm link).
I'll move it to a new issue.