Yup: how to compare the current value against the initial value in a `test`

Viewed 3170

Can you somehow create a .test that can have access to the initial value for a given field

For example an async "is email available" validation where the initial email value should be considered valid

const schema = Yup.object({
  email: Yup.string()
    .test('isAvailableAsync', 'The provided email is not available', async function (newValue) {
      // with alias the value is undefined
      // const initial = this.parent.emailInitial;

      const initial = this.parent.initialEmailRef; // it's always the same with `newValue`

      // email unchanged no need to do async call
      if (newValue == initial) return true;

      const result = await myAsyncCheck(email);
      return result.exists == false;
    })
  initialEmailRef: Yup.ref('email'), // tried with ref
})
  .from('email', 'emailInitial', true) // tried with alias
1 Answers

I ended up making a factory for the schema, something like this:

const getMySchema = ({ initialEmail }) => Yup.object({
  email: Yup.string()
    .test('isAvailableAsync', 'The provided email is not available', async (newValue) => {
      // email unchanged or returned to initial value no need to do async call
      if (newValue == initialEmail) return true;

      const result = await myAsyncCheck(email);
      return result.exists == false;
    })
})

And then use it like:

const schema = getMySchema({ initialEmail: user.email }); 
Related