How do you get createAsync to refetch or mutate?

I have a webpage where I get a list of items from a database. I want to take advantage of SolidStart's preloading and the other benefits of a createAsync based resource so I used it instead of createResource. Users can click a delete button next to each list item to delete it, and the list should update in response (possibly via an action). Now it occurs to me that the docs don't currently specify when, if or how createAsync based resources refetch data or if the data can be mutated (say by useSubmission to avoid a bunch of trips between client and server). Does anyone know how to do this?
8 Replies
Garrett Floyd
Garrett FloydOP7d ago
I just wanted to add that my initial assumption was that using one of the helper functions to invalidate the cache of the query would cause the createAsync based resource to update the UI but I've tried using reload, revalidate, and redirect for good measure in the return of my action and it hasn't been working so far.
peerreynders
peerreynders7d ago
One thing that is sometimes overlooked is that the query takes a name as the second argument. You need that name if you are going revalidate via a redirect which often done at the end of an action that results in a route change but also needs to compel various querys to refetch. If the query takes arguments those arguments act as a key to the cached result. So when revalidating it is essential to specify the matching key to force the refetch—that is what the key() and keyFor() methods are for.
redirect - SolidDocs
Documentation for SolidJS, the signals-powered UI framework
action - SolidDocs
Documentation for SolidJS, the signals-powered UI framework
query - SolidDocs
Documentation for SolidJS, the signals-powered UI framework
GitHub
solid-router/src/types.ts at 3c214ce2ceb9b7d9d39d143229a8c6145e83e6...
A universal router for Solid inspired by Ember and React Router - solidjs/solid-router
hannus
hannus7d ago
1. Preload the query and render its data inside a route component using createAsync. 2. Revalidate the key of the query rendered in the route component. This ensures that the query data is refreshed when an action is executed. The query functions like a GET method, while the action functions like a POST method. Just use revalidate directly if you don’t need to navigate to another page. Something like return revalidate(query.key).
peerreynders
peerreynders7d ago
data can be mutated (say by useSubmission
The intent isn't mutation as such. Typically the pending signal of the latest submission is used to show an optimistic value (which could be one of the submission arguments) in favour of the stale remote value. Once the submission is no longer pending the query will have updated and can be shown again as a fresh value. https://stackblitz.com/edit/solidjs-templates-7u2yad?file=README.md If you actually want to truly temporarily update a value then splice a createWritableMemo into the reactive graph, that way you can override it until the next time the actual reactive source updates. https://discord.com/channels/722131463138705510/1330302780250001449/1330366296956735582
peerreynders
StackBlitz
solid.js action cache interplay - StackBlitz
A Solid TypeScript project based on @solidjs/router, solid-js, typescript, vite and vite-plugin-solid
Solid Primitives
A library of high-quality primitives that extend SolidJS reactivity
Garrett Floyd
Garrett FloydOP3d ago
Thanks for the help everyone. The consensus seems to be that the helper functions like revalidate and reload should automatically cause the the createAsync based resource to refetch. However, this is not what I'm seeing. I did however find another solution. Consider the following code snippet const refreshTable = useSubmission(delEntryAction);
let tableEntries = createAsync(() => { let data; if (refreshTable.result === undefined){ data = getInitFetch(props.apiURL, limit(), pageNum()); } else { data = refreshTable.result; } return data; }); Ends up that the function body within createAsync is a reactive context so calling a signal there will trigger a refetch. Thankfully useSubmission outputs a signal based entity, so when my action resolves and gets a result it reads it into the useSubmission resource which then retriggers the createAsync resource as a derived signal, refetching the data.
peerreynders
peerreynders2d ago
However, this is not what I'm seeing.
For that to work the actual fetch function has to be wrapped in a query. An example I had from another topic: https://playground.solidjs.com/anonymous/de1ecf9e-b57b-42cc-b3c0-39e7b6927ad6 And also by default actions revalidate all active querys. Given that you are already using an action revalidation should “just work” provided the function used by createAsync accesses the fetch result via a query. revalidate version of the above without action: https://playground.solidjs.com/anonymous/ecfc76e8-3183-4298-8507-7aaae485025a
Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
Garrett Floyd
Garrett FloydOP2d ago
Thanks for your help again. I have been suspicious that I have been messing up the preload syntax somehow, so that what is preloaded is not connected to what I'm using in my createAsync resource. However, as I looked over my code to prepare a simplified example to get your opinion, I realized I had a "use server" directive at the top of the file I declared my queries in. That seem like a likely source for the problem I'm having and sure enough after removing it everything works as intend.
peerreynders
peerreynders2d ago
As it happens I also threw together an example with preload today: https://discord.com/channels/722131463138705510/910635844119982080/1349086382081183815

Did you find this page helpful?