Simple example from docs:
err => {
setSubmitting(false);
setErrors(err);
}
For now we have few _separate_ setter functions (like setErrors, setStatus, etc.), each with simple notation f(params) => void. API docs says that it is an imperative way to manage _formik's inner state_. And I think of them as a set of _setState callbacks_ where each one updates it's own _portion of formik state_. This way of thinking conflicts with example above - when you have to call multiple _setter callbacks_ in a row (finally, we're not executing React's setState this way).
More idiomatic api may look like this:
setSubmitting(false)
.then(() => setErrors(err));
Or React-way callback:
setSubmitting(false, () => setErrors(err))
But the simplest one still would be a plain f(params) => void function for the whole state:
setFormikState({ isSubmitting: false, errors: err })
Also, this way we can skip extra re-render.
Hi there.
First of all, API you proposed exposes Formik's internals - you have to know state keys (isSubmitting, errors, etc.) precisely. Typos in state keys would just "break" Formik's functionality.
Encapsulating those state keys into setter methods makes code less error prone. Also, Typescript and/or Flow help you those APIs.
Personally, I prefer using existing self describing setter methods over universal state setter.
What's yout use case for async, promise-like, setters?
I like this idea, not sure about the method name though:
setSubmitFinished(errors?)
setSubmitFinished() // update isSubmitting to false, remove submit errors
setSubmitFinished({ name: 'Required'}) // update isSubmitting to false, add provided errors
It'll be also great if there was a way to work with promises like this:
handleSubmit(values) {
return doApiCall(values)
.then(response => console.log('success')) // sets isSubmitting to false
.catch(e => transformErrors(e)) // sets isSubmitting to false, adds errors
}
setSubmitFinished(errors?) setSubmitFinished() // update isSubmitting to false, remove submit errors setSubmitFinished({ name: 'Required'}) // update isSubmitting to false, add provided errors
I find setter name and its functionality bit confusing.
How about two methods instead?
handleSubmit = async (values) => {
try {
await doApiCall(values);
setSubmitFinished()
} catch (errors) {
setSubmitFinishedWithErrors(errors)
}
}
@Andreyco yes, I'm also confused with a function name. I'd prefer stopSubmit or similar.
As per two methods - I don't think this separation is necessary since in both examples it's used for exactly the same thing (set isSubmitting flag, set submit errors).
The only difference is the errors object - empty when no errors or not empty with provided errors. See:
handleSubmit = async (values, { setSubmitFinished }) => {
try {
await doApiCall(values);
setSubmitFinished() // isSubmitting = false, errors = {}
} catch (errors) {
setSubmitFinished(errors) // isSubmitting = false, errors = {...errors}
}
}
// or stopSubmit
handleSubmit = async (values, { stopSubmit }) => {
try {
await doApiCall(values);
stopSubmit() // isSubmitting = false, errors = {}
} catch (errors) {
stopSubmit(errors) // isSubmitting = false, errors = {...errors}
}
}
@Andreyco
What's yout use case for async, promise-like, setters?
Just to convey a concept, not real case. Since current api feels too imperative.
API you proposed exposes Formik's internals
Fair point. But still, we can validate passed object's shape and with TS/Flow it would be easier too. If so, new api will be just very similar to (but not exposing 馃槈) Formik's internal state.
Tbf, when I first read api docs I thought that this is what setStatus is for.
@VladShcherbin
setSubmitFinished(errors?) or stopSubmit(errors?) seems pretty practical... but still kinda incomplete, inconsistent with rest of FormikBag api.
@eonwhite and I have discussed this multiple times offline. setFormikState(state: any) is too big of an escape hatch in our opinion. Think about it: <Child setThingState={this.setState} /> is a code smell.
I think I have a way for us to automatically call setSubmitting. Stay tuned
Any idea on how to achieve this?
@jaredpalmer any updates on this? Would be awesome to have isSubmitting automagically set to false if a returned promise from handleSubmit is resolved/rejected (like redux-form).
Also, it would be nice to also have errors to be set automagically if handleSubmit returns a rejected promise containing a "SubmissionError" (also like redux-form).
Thanks for a really awesome lib!
i think this is a good idea. will explore next week
Hola! So here's the deal, between open source and my day job and life and what not, I have a lot to manage, so I use a GitHub bot to automate a few things here and there. This particular GitHub bot is going to mark this as stale because it has not had recent activity for a while. It will be closed if no further activity occurs in a few days. Do not take this personally--seriously--this is a completely automated action. If this is a mistake, just make a comment, DM me, send a carrier pidgeon, or a smoke signal.
Did you have the change to explore the idea @jaredpalmer ?
The bad bot is trying to close the issue 馃敤
Hola! So here's the deal, between open source and my day job and life and what not, I have a lot to manage, so I use a GitHub bot to automate a few things here and there. This particular GitHub bot is going to mark this as stale because it has not had recent activity for a while. It will be closed if no further activity occurs in a few days. Do not take this personally--seriously--this is a completely automated action. If this is a mistake, just make a comment, DM me, send a carrier pidgeon, or a smoke signal.
Would be awesome to have
isSubmittingautomagically set to false if a returned promise fromhandleSubmitis resolved/rejected (like redux-form).Also, it would be nice to also have errors to be set automagically if
handleSubmitreturns a rejected promise containing a "SubmissionError" (also like redux-form).
I wouldn't even characterise this as "automagic" (which goes against the aims of this project), instead, async (values) => { if (good) return; else throw errors; } seems like a more natural API for communicating the results of submitting.
I had a use case with multiple forms being submitted one after another to different endpoints. I would have loved to control the submission from the master component (by controlling the children with refs). But without promises, I am forced to work with callbacks.
I was a bit disappointed that formik didn't have that feature.
@jaredpalmer any update on this?
I was really looking for something to solve this issue and the flow of this seems logical: async (values) => { if (good) return; else throw errors; }
Please advise.
... just to remove stale.
... just to remove stale.
This exists in v2
Most helpful comment
Did you have the change to explore the idea @jaredpalmer ?
The bad bot is trying to close the issue 馃敤