-
Notifications
You must be signed in to change notification settings - Fork 362
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WIP: Custom validator promises and options #1229
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -340,7 +340,20 @@ function validateCustom(attr, conf, err, options, done) { | |
done = options; | ||
options = {}; | ||
} | ||
conf.customValidator.call(this, err, done); | ||
|
||
if (conf.customValidator.length <= 1) { | ||
conf.customValidator.call(this, options) | ||
.then((isValid) => { | ||
if (!isValid) throw new Error(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. AFAICT, there are several outcomes of a custom validator:
I would like to preserve these options in the Promise mode too, i.e.
I think the cleanest solution is to expect the promise to resolve with a structured object instead of a single true/false value, although we can support boolean resolution to make simple cases simple to implement. // the value is valid
return Promise.resolve();
// the value is invalid, a message should be added by the framework
return Promise.reject();
return Promise.reject(err);
throw unhandledError;
// the value is invalid, a message was already added by the validator
return Promise.reject({ addMessage: false }); Here is a code snippet illustrating a possible implementation of my proposal: var result = conf.customValidator(...);
if (result.then && typeof result.then === 'function') {
result.then(
function onSuccess() { done(); },
function onFailure(reason) {
if (reason instanceof Error) {
done(err);
} else if (reason && reason.addMessage !== false) {
err(false);
} else {
err();
}
})
} Thoughts? |
||
done(); | ||
}) | ||
.catch(() => { | ||
err(); | ||
done(); | ||
}); | ||
} else { | ||
conf.customValidator.call(this, err, done, options); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think passing the options after the I am proposing the following change: if (conf.customValidator.length !== 4) {
// backwards compatibility with custom validators not accepting options
conf.customValidator.call(this, err, done);
} else {
conf.customValidator.call(this, options, err, done);
} Thoughts? |
||
} | ||
} | ||
|
||
/*! | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Our usual convention in other places where we support both callback/promise based functions, is to check for the return type of the function, instead of relying on the number of arguments.
My concern is that a custom validator accepting a single argument is a valid use case, see https://github.com/strongloop/loopback-datasource-juggler/pull/1229/files#diff-a1a277b8e694ce811867b2ac3e064ff8R626
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually: when defining a validator, user can provide
sync
flag to tell the framework whether the validator function is sync or async. Perhaps we can add another flag, e.g.promise
to distinguish between "old" custom validators using callbacks and the new Promise-based flavour?Just an idea to consider.