Skip to content

Commit

Permalink
feat: exposes context on mixed.test function and add originalValue to…
Browse files Browse the repository at this point in the history
… context (#1021)

* adds this context as second argument and originalValute to ctx

* edits mixed.test function on the Readme

* fix: adjust readme and push code changes
  • Loading branch information
abnersajr committed Oct 16, 2020
1 parent a56655d commit 6096064
Show file tree
Hide file tree
Showing 2 changed files with 7 additions and 5 deletions.
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -706,26 +706,27 @@ use the alternate signature to provide more options (see below):
let jimmySchema = string().test(
'is-jimmy',
'${path} is not Jimmy',
value => value === 'jimmy',
(value, context) => value === 'jimmy',
);

// or make it async by returning a promise
let asyncJimmySchema = string().test(
'is-jimmy',
'${path} is not Jimmy',
async (value) => (await fetch('/is-jimmy/' + value)).responseText === 'true',
async (value, context) => (await fetch('/is-jimmy/' + value)).responseText === 'true',
});

await schema.isValid('jimmy'); // => true
await schema.isValid('john'); // => false
```

test functions are called with a special context, or `this` value, that exposes some useful metadata and functions. Note that to use the `this` context the test function must be a function expression (`function test(value) {}`), not an arrow function, since arrow functions have lexical context.
test functions are called with a special context, or `this` value, that exposes some useful metadata and functions. Older versions just expose the `this` context using `function ()`, not arrow-func, but now it's exposed too as a second argument of the test functions. It's allow you decide which approach you prefer.

- `this.path`: the string path of the current validation
- `this.schema`: the resolved schema object that the test is running against.
- `this.options`: the `options` object that validate() or isValid() was called with
- `this.parent`: in the case of nested schema, this is the value of the parent object
- `this.originalValue`: the original value that is being tested
- `this.createError(Object: { path: String, message: String, params: Object })`: create and return a
validation error. Useful for dynamically setting the `path`, `params`, or more likely, the error `message`.
If either option is omitted it will use the current path, or default message.
Expand Down
5 changes: 3 additions & 2 deletions src/util/createValidation.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,13 @@ export default function createValidation(config) {
createError,
resolve,
options,
originalValue,
...rest,
};

if (!sync) {
try {
Promise.resolve(test.call(ctx, value)).then((validOrError) => {
Promise.resolve(test.call(ctx, value, ctx)).then((validOrError) => {
if (ValidationError.isError(validOrError)) cb(validOrError);
else if (!validOrError) cb(createError());
else cb(null, validOrError);
Expand All @@ -63,7 +64,7 @@ export default function createValidation(config) {

let result;
try {
result = test.call(ctx, value);
result = test.call(ctx, value, ctx);

if (typeof result?.then === 'function') {
throw new Error(
Expand Down

0 comments on commit 6096064

Please sign in to comment.