Await a resource inside a function?
This there a function which achieves something similar as my fictional "waitForResource" function here?
Or should I refactor my code?
29 Replies
If you do this under a transition, you can await an empty
startTransition()
call. It resolves when all resources resolve. I did not test this.What is the usecase? Conditional rendering you could do w
<Show/>
or <Suspense/>
.Unsure how to use the
startTranstition
in this case.
I need to use from data from my resource inside a submit callback. Specifically, it's like an "Add to cart" function, which needs to check some logic based on your cart, and a resource which fetches from some external APII think this is what you are looking for
data in this case will be
T
without keyed
data will be Accessor<T>
You would then pass
data
to the handleSubmit
function?yes exactly
onSubmit={e => handleSubmit(e, data)}
or somethingAight
Ty
ur welcome!
Thing is that the user now must wait for the resource to finish loading before clicking the button. Slightly different feel depending on how long that resource takes.
Could be just fine if <1s
Sure. But that was the behaviour of the original snippet, right? And sometimes that's exactly what we want. Just like Suspense, u can decide where u draw the boundary of what is and isn't rendered.
Original snippet rendered regardless of the resource being ready I believe. But if it solves the problem for OP, this is much simpler and preferred way, for sure!
ooo ur right
i misread the code
my bad
I would rather have an
await resource()
function, but sending the data from a Show
callback is fine. It's more of a TypeScript issueIll see if I can make a startTransition work in playground, but only much later today
Would be awesome if it were possible 😄
I played around a bit with the idea for a
waitForResource
: https://playground.solidjs.com/anonymous/f767499f-81c2-4c81-8f02-36e1f2b25177Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
Yup, that seems to do it
tweaked it a little bit: https://playground.solidjs.com/anonymous/1ec29bf5-a0e8-4e07-a925-38e3915ab6fd the previous version wouldn't resolve if the promise returned a falsey value.
Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
but ye i think u can get the main idea
Yup. I was just refactoring into the same ish thing
Would be nice if Solid had a
resource.promise()
which resolved into the resource, but this function works well 😄I agree. Kind of surprised nobody made a suggestion for it on https://discord.com/channels/722131463138705510/1085604933849595924 yet
Beauty of solid is that u can always make ur own wrapper if u really want that behavior https://playground.solidjs.com/anonymous/b4501633-864d-4de9-9f4e-562bab461e18
But now I made it I can see where this strategy fails, whereas regular resource doesn't: What if the fetcher is called again before the previous promise has been resolved? You are then awaiting an out-of-sync promise and end up with incorrect data.
<Show/>
and that waitForResource
-helper would just wait for the second promise is resolved.Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
I think that depends on how Solid createResource works? Does it cancel the running promise when calling
refetch
?this visualises a bit what i was talking about
left the
waitForResource
, right with .promise
Makes sense
this maybe?
nice
I'd say that the use case for a
waitForResource
is ultimately a misguided extension of the sequential illusion confusion prevalent in async JS development; i.e. an async
click handler is a red flag to begin with.
Also SolidJS manifests simple is better than easy and waitForResource
smacks of convenience over correctness.
Fundamentally createResource
and it's 2.0 replacement createAsync
are gateways from the async world into the sync reactive world- a transfer point from async events to synchronous reactive state.
So once you are on the left side of a resource (or createAsync
) you should be using reactive idioms. If you wish to exit from the reactive graph back into the async world then do so via an effect.
- The button could be clicked before the resource is ready. Let's say the UX is better if the button can be clicked before the resource is ready because the convenient solution would be to simply disable the button until the resource is ready.
- There is nothing in the OP that prevents the button from being spammed, effectively launching multiple, concurrent submissions; the handler being async
suggest the sequence of operations is relevant so at the very least the button should be disabled once it has been clicked, and only re-enabled once the sequence of operations has completed.
In other scenarios it may be necessary to queue each submission click with any data that should captured at the time of the click while other data is only added when it finally has its turn executing its sequence of operations.
So my solution looks quite a bit different:
https://playground.solidjs.com/anonymous/a6712ce2-5661-482c-b994-9b698f1aa537Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
SolidJS
Solid is a purely reactive library. It was designed from the ground up with a reactive core. It's influenced by reactive principles developed by previous libraries.