svelte-forms-lib icon indicating copy to clipboard operation
svelte-forms-lib copied to clipboard

isValid is not checking initial values

Open Bastian opened this issue 3 years ago • 7 comments

Summary

The isValid store is always true initially. This is unintended and it seems like this has not always been the case, since the example at https://svelte-forms-lib-sapper-docs-tjin.vercel.app/observables is working like intended (it is using an old version of this lib).

Steps to reproduce

Trivial, see example project.

Example Project

https://codesandbox.io/s/naughty-lichterman-m5jw7?file=/App.svelte

Thus button only gets disabled after you fill out the first field. It should be disabled initially.

What is the current bug behavior?

The isValid field is always true initially.

What is the expected correct behavior?

The isValid field should only be true initially if the initial values are valid.

Bastian avatar May 12 '21 19:05 Bastian

related to https://github.com/tjinauyeung/svelte-forms-lib/issues/20

larrybotha avatar May 13 '21 07:05 larrybotha

Anyone have a clever workaround for this issue?

mstibbard avatar Sep 02 '21 11:09 mstibbard

@mstibbard not ideal, but you should be able to pass initial form values through to updateInitialValues to trigger a validation: https://github.com/tjinauyeung/svelte-forms-lib/blob/f8bc5488b787d8b5b81eb855b90e5e76b565e7d3/lib/create-form.js#L184

larrybotha avatar Sep 12 '21 14:09 larrybotha

@larrybotha the workaround with updateInitialValues does not work for me. In my opinion isValid function does not work correctly. It should check errors only when there is no validation schema provided, otherwise it should verify schema. So instead of:

const isValid = derived(errors, $errors => {
  const noErrors = util.getValues($errors).every(field => field === NO_ERROR);
  return noErrors;
});

something like:

const isValid = derived((form, validationSchema), ($form, schema) => {
  const allPassed = util.isFormValidWithSchema($form, schema.fields);
  return allPassed;
});

where isFormValidWithSchema should be something like:

function isFormValidWithSchema(values, schema) {
  let isValid = true;

  const valuesWithKeys = Object.entries(values);

  for (const [key, value] of valuesWithKeys) {
    try {
      schema[key].validateSync(value);
    } catch {
      isValid = false;
    }
  }

  return isValid;
}

What do you think? I do not have idea how to code it in easy way, but essentially I believe isValid should work differently when validation schema is provided or not (and is it Yup or custom validation).

tomekrozalski avatar Sep 24 '21 17:09 tomekrozalski

I just saw comments on #20. Right, moving the validation section out of handleSubmit sounds reasonable. Maybe it should be in options like in Formik, validateOnMount or something like that 🤔

tomekrozalski avatar Sep 24 '21 19:09 tomekrozalski

@tomekrozalski I'd prefer a validate function that's not tied to any specific event, such as mount / destroy / anything else. The idea of associating validation with any specific event seems like a code-smell, whereas if we have a validate function, users can use it wherever they'd like.

Happy to accept a PR!

larrybotha avatar Nov 06 '21 05:11 larrybotha

Any update on this or a workaround that could be used until a fix is in place?

yasserlens avatar Jun 22 '22 11:06 yasserlens