-
Notifications
You must be signed in to change notification settings - Fork 94
promise
is undefined until first load/run
#92
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’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Thanks! This must have been an oversight on my part. Please do open a PR ❤️ |
Unfortunately I can only provide some tests that show the problem (see #93), I don't have a solution for it. |
Yes, thanks for that. I've reviewed your PR and given it some thought. I now think |
promise
is undefined until first load/run
@Khartir I've taken the liberty to rename this issue to focus on the value of |
Wouldn't that be problematic as a promise that never resolves/reject would cause a memory leak if it is subscribed to? On the other side of the same problem:
Wouldn't that lead to the promise being subscribed to once for each render until the promise resolves? I'm not really sure if it was a good idea to drop the promise-return-value from |
Good point. I'm not sure how the garbage collector handles this situation. At least you'll get the same unresolved promise each time, but that's still not ideal. That snippet is indeed not optimal. Subscribing to a promise should be done in const { run, promise } = useAsync(...)
useEffect(() => {
promise.then(onData, onError)
}, [promise]) I'll update the notes accordingly. However, it won't work with |
Hm. Maybe we could put more focus on onResolve/onReject/onCancel and leave the promise as an internal implementation detail? It would be a little more clumsy to use with formik (see my example in #75 ) - but without the promise returned by |
also having this issue, |
@bogdansoare Could you explain your use case? That will help me think of any alternatives that might also work for you. |
my use case is having to perform an action after the run completes, for a concrete example I have a form inside a modal dialog and I want to close the modal when the run completes <Form
onSubmit={async values => {
try {
await run({
name: values.name,
});
onClose();
} catch (error) {
console.log(error);
}
}} |
For this you should just be able to use |
I think the puzzle piece missing here is to be able to pass something to onResolve when calling run. At least, that would be great for my example in #75, where function MyForm() {
const { run } = useFetch(
"https://example.com",
{ method: "POST" },
{ defer: true }
);
return (
<div>
<h1>My Form</h1>
<Formik
initialValues={{ name: "jared" }}
onSubmit={(values, actions) => {
run(
{ body: JSON.stringify(values) },
{ onResolve: () => actions.setSubmitting(false) }
);
}}
render={props => (
<form onSubmit={props.handleSubmit}>
<Field type="text" name="name" placeholder="Name" />
<button type="submit">Submit</button>
</form>
)}
/>
</div>
);
} |
@ghengeveld |
@phryneas I'm open to changing the |
@bogdansoare I feel your pain. I'm actually inclined to restore the chainability of |
@ghengeveld yup, that's a little unfortunate - this could be mitigated though by placing the options argument to run at the front as an optional signature overload - something like this: function run<T extends any[]>(optionOverride: Partial<Options>, ...args: T);
function run<T extends any[]>(...args: T); |
@ghengeveld that sounds great, would be very helpful |
I'm currently trying to understand what the desired behavior of Would the better solution not be to only throw if there is neither a
When the
In other words,
I think it's acceptable to have If this is the desired behavior, a case could be made that in the non-rejecting case, |
I think I already suggested this over in react-async/future, but it might fit here, too: An alternative would be to resolve in all cases (thus not triggering an error) and resolving either with |
I've decided to just fix the issue at hand (promise being undefined), and care about the repercussions later. I've simply added a warning to the readme that you have to specify a rejection handler when chaining on As for the ongoing discussion, let's take that into account while designing the future version of React Async / Async Library. One idea I have right now is to introduce a const noop = () => {}
const then = (onResolve, onReject = noop) => promise.then(onResolve).catch(onReject) |
In Version 8 the
run
method no longer returns a promise. Instead thepromise
prop should be used. However, when using useFetch, thepromise
property isundefined
.Here is a test that demonstrates this:
I'll also add a Pull-Request with these failing tests.
The text was updated successfully, but these errors were encountered: