S
SolidJS16mo ago
Merlin

Refetching Route Data with Solid Router

Is there any way to refetch (revalidate) the data functions with @solidjs/router? (not Solid Start; I'm using Vite) - I'm mutating something on the backend and would like to make sure the data is up to date - Returning the whole createResource return value kind of works -- calling refetch correctly refetches the data, but mutate doesn't work. - Additionally, I'd like to refetch/revalidate all resources somehow. Is that possible?
68 Replies
Jules
Jules16mo ago
Happy to take a look, what do you mean by mutate doesn't work? Also posting some code would be helpful for us to lend a hand
Merlin
MerlinOP16mo ago
// --- App.tsx ---

const Project = lazy(() => import("./pages/dashboard/Project"));
const getProjectData = ({ params }) => createResource(() => fetch(...));

<Routes>
<Route
path="/project/:id"
component={Project}
data={getProjectData}
/>
</Routes>


// --- Project.tsx ---

function Project() {
// SolidJS docs recommend returning createResource()[0]
// so I wouldn't have access to refetch() if going by the docs.
//
// ...then how do I refresh?
const [project, { refetch, mutate }] = useRouteData();

function someCallback() {
// This should trigger an update of the `project` signal immediately,
// since mutate is a signal setter, but it doesn't!
//
// The data itself gets updated -- when components rerender, the new values are shown.
// So this is a reactivity issue.
mutate({ title: "foobarbaz" });
}

return <div>{project().title}</div> // mutate() will not trigger a DOM update here
}
// --- App.tsx ---

const Project = lazy(() => import("./pages/dashboard/Project"));
const getProjectData = ({ params }) => createResource(() => fetch(...));

<Routes>
<Route
path="/project/:id"
component={Project}
data={getProjectData}
/>
</Routes>


// --- Project.tsx ---

function Project() {
// SolidJS docs recommend returning createResource()[0]
// so I wouldn't have access to refetch() if going by the docs.
//
// ...then how do I refresh?
const [project, { refetch, mutate }] = useRouteData();

function someCallback() {
// This should trigger an update of the `project` signal immediately,
// since mutate is a signal setter, but it doesn't!
//
// The data itself gets updated -- when components rerender, the new values are shown.
// So this is a reactivity issue.
mutate({ title: "foobarbaz" });
}

return <div>{project().title}</div> // mutate() will not trigger a DOM update here
}
Example with comments explaining the problems ☝️ I'm probably just doing something dumb (or this isn't supported at all)
Jules
Jules16mo ago
No, no the solid docs are a work in progress I afaik so a lot of things aren't well documented but are fully supported. So when you call mutate you expect it to mutate the resource object, but are you also mutating it on the server so that if it refetches the new data would be the same as the "feebarbaz" object? Oh I see, interesting, I just read the comments and you're saying the data in project object is updated as per the call to the setter but it doesn't cause a rerender despite using them in a reactive context i.e calling the getter? So the way I normally go about this is: - someCallback realizes that the data needs to be updated and sends a tRPC call to the backend with the new object, then I trigger a refetch of the async data so I don't have to mutate my values at all, you can do optimistic updates by using the mutate function and then reconciling with the servers response, does this sound like what your implementation is?
Jules
Jules16mo ago
https://start.solidjs.com/api/useRouteData#retrieving-data-from-the-routedata-function you can't blame yourself for not knowing how this works, the docs are pretty sparse on the setter and getters
SolidStart Beta Documentation
SolidStart Beta Documentation
Early release documentation and resources for SolidStart Beta
Merlin
MerlinOP16mo ago
Yes! Exactly
Jules
Jules16mo ago
That is certainly very strange
Merlin
MerlinOP16mo ago
you can do optimistic updates by using the mutate function
Exactly what I'm trying to do refetching works, but if the user has a slow connection, it comes out all janky
Jules
Jules16mo ago
Right okay cool, so we're on the same page. What do you mean by janky? like I know it means not great lol
Merlin
MerlinOP16mo ago
Oh I just meant the user experience lmao
Jules
Jules16mo ago
gotcha Like flickering and layout shift?
Merlin
MerlinOP16mo ago
Yeah
Merlin
MerlinOP16mo ago
This isn't the codebase I'm working on right now, but take a look at this:
Merlin
MerlinOP16mo ago
After unfocusing the input, there's a 1-2s delay until it's done refetching I want to optimistically update, but mutate doesn't seem to work But I may be doing something stupid, I'll definitely try again to make sure It's weird because refetch works, though Is there any possibility this isn't related to mutate, but to list rendering? The stuff I'm trying to mutate is an array rendered by <For> So my mutate call ends up looking like this:
const idToUpdate = 123;

const upd = projects(); // route data resource getter

// array copy alternative that doesn't work either:
// const upd = [...projects()];

upd.find(p => p.id === idToUpdate)?.title = "some new title";

mutate(upd);
const idToUpdate = 123;

const upd = projects(); // route data resource getter

// array copy alternative that doesn't work either:
// const upd = [...projects()];

upd.find(p => p.id === idToUpdate)?.title = "some new title";

mutate(upd);
Jules
Jules16mo ago
Oh totally get the problem, but I haven't yet attempted this in solid, I am rewriting my Next.js and React app in Solid and I managed to do it in two nights, plus some finagling - which coincidentally, leaves me with one more job to do, update a users profile optimistically using Solid's createResource, so I am in the same boat as you
Merlin
MerlinOP16mo ago
oh lol
Jules
Jules16mo ago
So you're mutating to filter an array basically?
Merlin
MerlinOP16mo ago
I'm mutating one element in the array
Jules
Jules16mo ago
gotcha, and the array is the config array of that card
Merlin
MerlinOP16mo ago
Each card represents one element in the array Each card is a project
Jules
Jules16mo ago
right okay, understood
Merlin
MerlinOP16mo ago
Either way, I think this is either a bug with @solidjs/router or just unsupported
Jules
Jules16mo ago
and so you anticipate mutate to work instantly, which I would agree is true and refetch should then reconcile
Merlin
MerlinOP16mo ago
I might be doing something stupid but I can't see it
Jules
Jules16mo ago
have you tried with dummy fetches?
Merlin
MerlinOP16mo ago
Right
Jules
Jules16mo ago
just to see?
Merlin
MerlinOP16mo ago
dummy fetches? Refetching works, just optimistic updates (mutate) don't That's why I'm so baffled by it lol
Jules
Jules16mo ago
like
const getData = () => {
setTimeout(() => {
console.log('waiting....')
}, 2000)
return {...data}
}
const getData = () => {
setTimeout(() => {
console.log('waiting....')
}, 2000)
return {...data}
}
to eliminate the server as a variable in the issue and ensure that the delay of optimistic update is not the server delay if that makes sense i.e is mutate basically refetching and not setting
Merlin
MerlinOP16mo ago
No, mutate always optimistically updates
Jules
Jules16mo ago
okay huh weird
Merlin
MerlinOP16mo ago
createResource is really just createSignal + a wrapper around fetch
Jules
Jules16mo ago
yeah ik
Merlin
MerlinOP16mo ago
and I managed to do it in two nights
That's absolutely crazy And huge for solidjs adoption
Jules
Jules16mo ago
It was, I mean I am crazy and worked about 12hrs a day on it
Merlin
MerlinOP16mo ago
I'm doing basically the same, it's taking slightly longer but I'm rewriting more
Jules
Jules16mo ago
and the app is only about 20-30 pages
Merlin
MerlinOP16mo ago
"only" that's absolutely crazy
Jules
Jules16mo ago
it's an e-commerce app with a backend dashboard, auth, etc. most of the react JSX was portable
Merlin
MerlinOP16mo ago
I think if anything is gonna see mainstream adoption of the new frameworks it's SolidJS
Jules
Jules16mo ago
only the business logic needed some minor tweaking and the solidjs DX is sooooo much better than Next
Merlin
MerlinOP16mo ago
Are you using solid start?
Jules
Jules16mo ago
I agree, though some people seem to be really into Svelte
Merlin
MerlinOP16mo ago
Or astro/vite/...?
Jules
Jules16mo ago
yep
Merlin
MerlinOP16mo ago
How's that working out for you? Any bugs/issues?
Jules
Jules16mo ago
No it's been great, I might run into the same thing you're running into in a minute, I am coding the page where users can update their profiles in the same optimistic with backend refetch
Merlin
MerlinOP16mo ago
Not sure if you will I'm using SolidJS + Vite, so no Solid Start
Jules
Jules16mo ago
Some random issues where my client side javascript stopped hydrating for no apparent reason
Merlin
MerlinOP16mo ago
@solidjs/router only in dev or prod?
Jules
Jules16mo ago
Oh interesting, what made you choose that? in both actually
Merlin
MerlinOP16mo ago
Huh
Jules
Jules16mo ago
I just rolled back and slowly introduced the stashed changes back and I still have yet to recreate the issue
Merlin
MerlinOP16mo ago
I don't need SSR that badly, and marketing pages I can move to astro or prerender "manually" if it affects SEO (I think solid has good SSR support without Solid Start) Since I'm building more of an app
Jules
Jules16mo ago
Fair enough, what is your project? if I may ask I am also working on an open-source blog/cms starter app for the solid community
Merlin
MerlinOP16mo ago
Doing a transcription/content generation thingy Happy to share more soon if you're interested :P
Jules
Jules16mo ago
ooo neat, yeah I am all ears are you going to monetize or open-source
Merlin
MerlinOP16mo ago
Oh, it's for a company I'm doing freelance
Jules
Jules16mo ago
Ohhhh interesting okay
Merlin
MerlinOP16mo ago
The current version of the app is with Remix.run But I'm having a couple issues, not necessarily because of Remix, but I'm building more of an app
Jules
Jules16mo ago
yeah I have never worked with Remix yeah I get it, hopefully everything is on time and you're making good money on the project then
Merlin
MerlinOP16mo ago
Thanks, appreciate it a lot 😄
Jules
Jules16mo ago
Of course
Merlin
MerlinOP16mo ago
If you don't mind me asking... what are you working on? o:
Jules
Jules16mo ago
I am working on the aforementioned blog cms platform open-source solidjs ecosystem and I am working on a personal project where I resell hobby chemistry/experimental lab equipment and supplies and merch on an e-commerce platform, but I am doing a really thorough job of the e-commerce platform so I can reuse the code for future endeavors or an open-source thing again I also started to look into developing an auth library but Lucia Auth did almost exactly what I envisioned, basically AuthJs but less opinionated though they don't have an officially supported solid package
Merlin
MerlinOP16mo ago
Wow, that sounds awesome -- good luck with all of those :) I'd love to take a look at the lab equipment one
Jules
Jules16mo ago
I might be able to show you, it might require some staging first it's the only not open-source of the list XD One aspect of it that will be though is a cheminformatics API but that is only in the very beginning stages
Merlin
MerlinOP16mo ago
Oh, no worries, I thought you had it live somewhere Would love to see it once it's live :)
foolswisdom
foolswisdom16mo ago
Very odd. What happens if you move the resource call into the component body? Not that I expect that to make a difference
Want results from more Discord servers?
Add your server