Search code examples
reactjsreact-final-form

React final form - Validation return key & value instead of string


Currently I am using React-Final-Form and I want to return an object or key/value instead of an error string.

This is my validation rule:

validate={values => {
        const errors = {}
        if (!values.username) {
          errors.username = 'Required'
        }
        if (!values.password) {
          errors.password = 'Required'
        }
        if (!values.confirm) {
          errors.confirm = 'Required'
        } else if (values.confirm !== values.password) {
          errors.confirm = 'Must match'
        }
        return errors
      }}

This prints the error:

  {meta.error && meta.touched && <span>{meta.error}</span>}

Instead of seeing Required I want to be able to say: key -> 'required' and the value of this key is 'please fill in the field'. I know it is possible to change the string of 'Required' but I want to have a key value. I cannot make an object it won't allow me.

Desired result: {meta.error && meta.touched && {meta.error.required}}

UI will show: Please fill in the field

This playground of react-final-form can be used since it is almost the same:

https://final-form.org/docs/react-final-form/examples/record-level-validation


Solution

  • Well, you can do it like this:

      <Form
          onSubmit={onSubmit}
          validate={values => {
            const errors = {}
            if (!values.username) {
              errors.username = { required: true, text: "Please fill in the field"} // this is used as an object
            }
            if (!values.password) {
              errors.password = 'Required'
            }
            if (!values.confirm) {
              errors.confirm = 'Required'
            } else if (values.confirm !== values.password) {
              errors.confirm = 'Must match'
            }
            return errors
          }}
          render={({ handleSubmit, form, submitting, pristine, values }) => (
            <form onSubmit={handleSubmit}>
              <Field name="username">
                {({ input, meta }) => {
                  console.log(meta) // to see the structure of your meta
                  return (
                  <div>
                    <label>Username</label>
                    <input {...input} type="text" placeholder="Username" />
                    {meta.error && meta.touched && <span>{meta.error.text}</span>}
    // then here if you still want to use string you can put what you need
                      </div>
                    )}}
                  </Field>
                  <Field name="password">
                    {({ input, meta }) => (
                      <div>
                        <label>Password</label>
                        <input {...input} type="password" placeholder="Password" />
                        {meta.error && meta.touched && meta.required && <span>{meta.error}</span>}
                      </div>
                    )}
                  </Field>
                  <Field name="confirm">
                    {({ input, meta }) => (
                      <div>
                        <label>Confirm</label>
                        <input {...input} type="password" placeholder="Confirm" />
                        {meta.error && meta.touched && <span>{meta.error}</span>}
                      </div>
                    )}
                  </Field>
                  <div className="buttons">
                    <button type="submit" disabled={submitting}>
                      Submit
                    </button>
                    <button
                      type="button"
                      onClick={form.reset}
                      disabled={submitting || pristine}
                    >
                      Reset
                    </button>
                  </div>
                  <pre>{JSON.stringify(values, 0, 2)}</pre>
                </form>
              )}
            />