Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

setSubmitting not working #1957

Closed
czaplej opened this issue Oct 29, 2019 · 30 comments
Closed

setSubmitting not working #1957

czaplej opened this issue Oct 29, 2019 · 30 comments

Comments

@czaplej
Copy link

czaplej commented Oct 29, 2019

馃悰 Bug report

Current Behavior

setSubmitting method not changing FormikProps isSubmitting

Your environment

Software Version(s)
Formik 2.0.3
React 16.10.2
TypeScript 3.6.4
Browser Opera
npm/Yarn 1.19.1
Operating System Windows10
@warnellw
Copy link

Experiencing a similar issue. isSubmitting is automatically getting set back to false in V2. According to the docs and the behavior in V1, isSubmitting must manually be set to false in the handler.

@artemlatark
Copy link

same problem

@numToStr
Copy link

I first thought that my form has some issues. After debugging I can say that setSubmitting is working but the issue is that isSubmitting set back to false after handleSubmit get executed.

@czaplej
Copy link
Author

czaplej commented Oct 30, 2019

I first thought that my form has some issues. After debugging I can say that setSubmitting is working but the issue is that isSubmitting set back to false after handleSubmit get executed.

true, need to create for example promise or async and await for response submit,

Full example
https://codesandbox.io/s/formik-v2-template-9j5xz

@srowe0091
Copy link

I'm also experiencing this issue. the docs say when you call handleSubmit(e) isSubmitting is set to true. This is indeed happening, but it is immediately getting set to false right after for some reason.

@warnellw
Copy link

warnellw commented Oct 30, 2019

It appears from the source that the submit handler is now expecting a Promise and Formik will set the isSubmitting state back to false when the promise resolves. If the submit handler is not a promise it resolves immediately.

Is this the new API of V2?

@srowe0091
Copy link

I am now returning my promise handler and its now working, but I dont like this approach, because if you have chain promises, then isSubmitting will return false on the first promise, and basically the loading indicator will go away, but theres still more promises to fulfill afterwards. I'd prefer to manually reset isSubmitting, or add a flag to not auto update isSubmitting to false

@paulkre
Copy link

paulkre commented Nov 2, 2019

Can someone fix this or change the documentation, please? This is basic functionality for most forms and I went almost insane trying to figure out what was wrong 馃槄

@Tigge
Copy link
Contributor

Tigge commented Nov 2, 2019

It's a bit unclear which behaviour is the intended one for version 2. If we can get some clarification I'd be happy to create a pull request.

@kbi-daniel
Copy link

It's a bit unclear which behaviour is the intended one for version 2. If we can get some clarification I'd be happy to create a pull request.

@Tigge For what it's worth, my vote would be to duplicate as closely as possible the behavior of Version 1, since I believe this would alleviate the need to refactor code to address this issue and in turn make migration to Version 2 as seamless as possible.

Just as an example, I have been using isSubmitting in my fields and buttons to disable functionality.
However, after migrating to Version 2, I now get a weird effect where my fields and buttons are made active for a split second before I have an opportunity to transition away. From a strictly selfish perspective, I'd hate to have to refactor all these forms in order to stay current with the latest version of Formik.

68047456-adf29f00-fc9b-11e9-9f51-ed999ebb6968

@jaredpalmer
Copy link
Owner

You should need to return a promise I thought. Manual setSubmitting calls should still work (mimic v1 behavior)

@Tigge
Copy link
Contributor

Tigge commented Nov 2, 2019

@jaredpalmer: Previous behaviour is here https://github.com/jaredpalmer/formik/blob/version-1.5.8/src/Formik.tsx#L444. Nothing in formik touched the isSubmitting flag in version 1. You had to reset it yourself once you where done submitting. In the documentation this is also mentioned:

you call setSubmitting(false) in your handler to finish the cycle

In version 2 the behaviour is here https://github.com/jaredpalmer/formik/blob/master/src/Formik.tsx#L713, once your onSubmit function is done, resolved or rejected doesn't matter, formik will reset it to false for you.

I agree with @kbi-daniel that following version 1 behaviour would be nice - at least if you want to make the transitioning easier. If not - at least one of rejecting or resolving should keep the isSubmitting state.

@Tigge
Copy link
Contributor

Tigge commented Nov 2, 2019

Also the onSubmit function is typed as onSubmit: (values: Values, formikHelpers: FormikHelpers<Values>) => void now.

@alexisbg
Copy link

alexisbg commented Nov 2, 2019

And it's also very annoying when you expect an async result from a Redux state.

Please allow us to disable this new behaviour of isSubmitting and allow us to use setSubmitting again.

Tigge added a commit to Tigge/formik that referenced this issue Nov 2, 2019
In version 2 the behaviour of isSubmitting was changed from having the
user handle it's state after submitting to always resetting it to false
after the onSubmit handler had returned (or it's promise). This reverts
it back to the version 1 behaviour of not touching the isSubmitting
state after the onSubmit handler has been called.

Solves: jaredpalmer#1957
Tigge added a commit to Tigge/formik that referenced this issue Nov 2, 2019
In version 2 the behaviour of isSubmitting was changed from having the
user handle its state after submitting to always resetting it to false
after the onSubmit handler had returned (or it's promise). This reverts
it back to the version 1 behaviour of not touching the isSubmitting
state after the onSubmit handler has been called.

Solves: jaredpalmer#1957
@Tigge
Copy link
Contributor

Tigge commented Nov 2, 2019

I've created a pull request (#1987) to revert the behaviour to how it functioned in version 1. If we want some other behaviour I'd be happy to adjust it or create a new pull request.

@tphan18
Copy link

tphan18 commented Nov 4, 2019

It will introduce a subtle bug that user can still click the button when you direct user to another page after the promise is fulfilled.

const onSubmit = (...) => {
  return submit(...).then(() => {
     Router.push(...) // The button is already enabled so user can click the button again. 
  })
}

Tigge added a commit to Tigge/formik that referenced this issue Nov 8, 2019
In version 2 the behaviour of isSubmitting was changed from having the
user handle its state after submitting to always resetting it to false
after the onSubmit handler had returned (or it's promise). This reverts
it back to the version 1 behaviour of not touching the isSubmitting
state after the onSubmit handler has been called.

Solves: jaredpalmer#1957
@j0b0sapi3n
Copy link

I'm seeing this issue in v2 as well. I see there's a PR to change it back to v1 behavior which I support.

@srmasharad
Copy link

srmasharad commented Nov 13, 2019

Yeah I've also face the same issue in my latest project where I install the formik verison 2.0.3 where isSubmitting is not working and I switched back to the previous version 1.5.8 and it works for me.

@vpartington
Copy link

Same here. I've switched back to v1.5.8 for now. I hope the PR gets will get merged soon!

@amr
Copy link
Contributor

amr commented Nov 18, 2019

This got me too. Perhaps a way of making both approaches (old + new) work is to check if the submit handler returns a promise, and only then trigger the new behavior.

I'm using redux saga to handle side effects so my method returns immediately after dispatching my actions and later on as part of my saga I'd setSubmitting to false

@nperrier
Copy link

This was confusing as well. I think the doc should at least be updated to indicate a Promise needs to be returned for it to work as indicated.

@jaredpalmer
Copy link
Owner

This got me too. Perhaps a way of making both approaches (old + new) work is to check if the submit handler returns a promise, and only then trigger the new behavior.

This is ideal and easy to implement. Can someone open a PR?

@Tigge
Copy link
Contributor

Tigge commented Nov 19, 2019

This got me too. Perhaps a way of making both approaches (old + new) work is to check if the submit handler returns a promise, and only then trigger the new behavior.

This is ideal and easy to implement. Can someone open a PR?

@jaredpalmer but should there not be a way to keep the form in an unsubmitted state in the new promise version?

Tigge added a commit to Tigge/formik that referenced this issue Nov 20, 2019
In version 2 the behaviour of isSubmitting was changed from having the
user handle its state after submitting to always resetting it to false
after the onSubmit handler had returned (or it's promise).

This adds back to the version 1 behaviour of not touching the
isSubmitting state after the onSubmit handler has been called if we
don't return a promise in the onSubmit handler.

Solves: jaredpalmer#1957
@Tigge
Copy link
Contributor

Tigge commented Nov 20, 2019

I've updated my PR to enable both old + new behavior. The documentation is not updated yet there. However I don't think that is a good solution.

I can understand having isSubmitting as an internal state, only being true while the onSubmit handler runs. In that case there might be no need to have the setSubmitting function available either.

The use case for the old method was also to have it as a this form is submitted and should not be submittable again.

Either continue only with v2, allow it to be left in an isSubmitting state or just add an example on how to mimic that use case with react state or similar. And in either case, clarify how things really work in the documentation.

Either way (even if we do the dual version) I'll continue to update the PR.

jaredpalmer pushed a commit that referenced this issue Nov 21, 2019
In version 2 the behaviour of isSubmitting was changed from having the
user handle its state after submitting to always resetting it to false
after the onSubmit handler had returned (or it's promise).

This adds back to the version 1 behaviour of not touching the
isSubmitting state after the onSubmit handler has been called if we
don't return a promise in the onSubmit handler.

Solves: #1957
@jaredpalmer
Copy link
Owner

Fixed in 2.1

@ahtashamabbasse
Copy link

ahtashamabbasse commented Apr 6, 2020

Fixed in 2.1

Causing issue in "formik": "^2.1.4"

@WestonThayer
Copy link

I can still repro this on 2.1.4 as well. See https://codesandbox.io/s/formik-codesandbox-template-6b1s9?file=/index.js

The current docs are accurate:

IMPORTANT: If onSubmit is async, then Formik will automatically set isSubmitting to false on your behalf once it has resolved. This means you do NOT need to call formikBag.setSubmitting(false) manually. However, if your onSubmit function is synchronous, then you need to call setSubmitting(false) on your own.

So either this issue should be re-opened, or we should accept the new behavior.

@fuvizzo
Copy link

fuvizzo commented Jun 3, 2020

i solved like this:

  const onSubmitClickHandler = (data, { setSubmitting }) => {
    const submit = async () => {
      const isAuthenticated = await props.signInWithEmailAndPassword(data);
      setSubmitting(false);
      if (isAuthenticated) history.push('/dashboard/menu-list');
    };
    submit();
  };

  return (    
      <Formik
        initialValues={initialValues}
        validationSchema={createSignInSchema(FormValidationErrors)}
        onSubmit={onSubmitClickHandler}
      >

I think it can be a workaround

@itskarl
Copy link

itskarl commented Dec 4, 2020

i solved like this:

  const onSubmitClickHandler = (data, { setSubmitting }) => {
    const submit = async () => {
      const isAuthenticated = await props.signInWithEmailAndPassword(data);
      setSubmitting(false);
      if (isAuthenticated) history.push('/dashboard/menu-list');
    };
    submit();
  };

  return (    
      <Formik
        initialValues={initialValues}
        validationSchema={createSignInSchema(FormValidationErrors)}
        onSubmit={onSubmitClickHandler}
      >

I think it can be a workaround

Thanks! This was the solution for me.

@mohammadfayiztp
Copy link

IF YOU USING REDUX STORE OR ANY ASYNC

FROM COMPONENT
////////////

 await new Promise((resolve, reject) => {
            dispatch(
              updateSalesOrder(
                {
                  ...data,
                  arrayDocuments: data.arrayDocuments.filter((x) => x.id === '').map((x) => getFileType(x))
                },
                resolve,
                reject
              )
            );
          })
            .then(() => {
              navigate(PATH_DASHBOARD.salesOrder.list);
            })
            .catch(() => {
              enqueueSnackbar('Something went wrong', {
                variant: 'erorr',
                action: (key) => (
                  <MIconButton size="small" onClick={() => closeSnackbar(key)}>
                    <Icon icon={closeFill} />
                  </MIconButton>
                )
              });
            });

FROM REDUX ACTION
////////////////

export const updateSalesOrder = (variables, resolve, reject) => async (dispatch) => {
  dispatch(loadingSalesOrder(UPDATE_SALES_ORDER_INIT, variables.salesOrderId));
  const resp = await UpdateRequest(variables);
  if (resp.status) {
    dispatch(successSalesOrder(UPDATE_SALES_ORDER_SUCCESS, resp.data));
    resolve();
  } else {
    dispatch(errorSalesOrder(UPDATE_SALES_ORDER_FAIL, { msg: resp.msg, variables }));
    reject();
  }
};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests