Formik: [v2] Setting a MomentJS object as a form value triggers an invalidType error when using Yup to validate a date field. This was not an issue in v1.

Created on 29 Oct 2019  路  10Comments  路  Source: formium/formik

馃悰 Bug report

Current Behavior

I have a custom date range picker that uses setFieldValue to propagate start and end dates to my Formik form. This date range picker does everything using Moment JS (like the rest of my codebase and Yup (I think) do). When I set a field to this MomentJS object, it triggers an invalidDate error in my Yup form validation.

Expected behavior

In v1, setting a MomentJS object to a date field was a valid action.

Reproducible example

Validate the date field of a form using Yup like so:

  departDate: Yup.date()
    .required("You must specify a depart date")
    .min(moment().set({ hour: 0, minutes: 0 }), "You cannot depart in the past")
    .typeError("Invalid date"),

In a custom component, use setFieldValue using something like:

setFieldValue('departDate', new Moment())

This triggers a validation error with "Invalid date" (triggered by the typeError Yup helper).

Suggested solution(s)

In v1, would Formik automatically convert Moment JS objects to standard Date objects? I have no idea what else would have changed between v1 and v2. Does Formik interact with Yup differently now?

I could just use a transform to transform the Moment object to a date, but I would still like to understand what changed between v1 and v2.

Additional context

Your environment

| Software | Version(s) |
| ---------------- | ---------- |
| Formik | . 2.0.3
| React | . 16.8.3
| TypeScript | . none
| Browser | . none
| npm/Yarn | yarn 1.17.3
| Operating System | Mac OSX

Most helpful comment

Would love to see this released as a 2.0.4 soon (this breaks every form with a date or complex object in it)

All 10 comments

Having the same issue with dates parsed with date-fns/parseISO

initialValues={{
          firstName: getValueOrDefault(user.firstName),
          lastName: getValueOrDefault(user.lastName),
          birthDate: user.birthDate ? parseISO(user.birthDate) : null,
.....

and in validationScheme birthDate: Yup.date(),.

Added some logging in the yup implementation to see the input. This is my log statement (v is the value):

console.log(v, Object.prototype.toString.call(v),  typeof v.getTime, 'yup logging');

This is the result:
Skjermbilde 2019-10-29 kl  12 55 32

So it is called twice and on the first run it looks like a empty object (has no getTime function and the tostring returns [object Object]. On the 2 run its a date, but not a valid one.

I have tried to run it directly against yup, and then it validates (See https://codesandbox.io/s/falling-moon-dqfim?fontsize=14).

And I am sure that the date is valid and set in the formik state when validation is running.

Did some more investigation: Logged values before and after prepareDataForValidation. the date before prepareDataForValidation is date object. After prepareDataForValidation the date property is an empty object.

I saw just now that this is already solved in this PR: https://github.com/jaredpalmer/formik/pull/1940.
Good that I checked PRs before starting on my own PR :)

Fixed in PR: #1949, so @jaredpalmer can we close it?

Awesome, thank you all!

Would love to see this released as a 2.0.4 soon (this breaks every form with a date or complex object in it)

Would love to see this released as a 2.0.4 soon (this breaks every form with a date or complex object in it)

Any word on if this will make a 2.0.4 release, and timing for said release?

I'm waiting too for this fix to be released

@jaredpalmer - Any possibility of getting a version bump for this issue? It's a blocker for V2 for us.

Seeing this work in the newly-cut 2.0.4 build. Thanks @jaredpalmer

Was this page helpful?
0 / 5 - 0 ratings