S
SolidJS3w ago
sh03

`reload`/`revalidate` + other response (e.g. `json` or `redirect`)

I'm kinda confused as to why reload and revalidate has to be part of the response from an action. How can I both reload/revalidate cache keys and also redirect or return some other response from an action?
34 Replies
TaQuanMinhLong
the revalidate is actually interconnected with query, which just simply revalidating the global cache Map i actually invent myself a similar behavior with custom revalidation approach (i dont use solidjs router's query fn) :Worry_CoffeeHMM:
sh03
sh03OP3w ago
Right, but isn't the fact that you have to return a "reinvalidate" response from an action kinda limiting? What if I want to return something else? Or what am I missing?
TaQuanMinhLong
you can just return the result instead, and the revalidation part is instead stayed within onComplete attribute of action's option oh they didn't mention it in the docs it's a new feature
TaQuanMinhLong
GitHub
solid-router/src/data/action.ts at main · solidjs/solid-router
A universal router for Solid inspired by Ember and React Router - solidjs/solid-router
sh03
sh03OP3w ago
What do you call in the onComplete? revalidate?
TaQuanMinhLong
yeah
sh03
sh03OP3w ago
Seems like onComplete is just called and the response ignored. Wouldn't returning revalidate from onComplete also get ignored?
TaQuanMinhLong
it runs as an effect the action's result is what being returned not onComplete
sh03
sh03OP3w ago
So what you are saying is that if I do this:
export const someAction = action(
async () => {
"use server";
const response = await someServerFn();
revalidate(someQuery.keyFor()); // this is ignored
return response;
}
);
export const someAction = action(
async () => {
"use server";
const response = await someServerFn();
revalidate(someQuery.keyFor()); // this is ignored
return response;
}
);
then here the revalidate is ignored because it's not returned. But if I do this:
export const someAction = action(
async () => {
"use server";
return await someServerFn();
},
{
onComplete: () => {
revalidate(someQuery.keyFor()); // this is NOT ignored
},
}
);
export const someAction = action(
async () => {
"use server";
return await someServerFn();
},
{
onComplete: () => {
revalidate(someQuery.keyFor()); // this is NOT ignored
},
}
);
then here it's not ignored despite the fact that it's not returned?
Brendonovich
Brendonovich3w ago
Most simply, you can use json instead of reload. It accepts the same revalidate config as reload but allows returning data too
TaQuanMinhLong
:_Worry_Wow:
sh03
sh03OP3w ago
What about invalidating the cache AND redirecting instead?
Brendonovich
Brendonovich3w ago
Invoking an action will automatically invalidate every cache by default
sh03
sh03OP3w ago
Now I'm even more confused. If invoking an action automatically invalidates every cache by default then why is there a revalidate util?
Brendonovich
Brendonovich3w ago
For if you only want to invalidate specific caches Since invalidating every cache will cause every cache currently being rendered to refetch Oh the revalidate util function is just for invalidating any cache at runtime outside of actions this is about the revalidate arg to the response helpers
sh03
sh03OP3w ago
I have a classic: - Nav: query that shows either "Sign in" (if not logged in) or "Profile" (if logged in) - Sign out button that calls an action If I click signout and call the action to sign out then the navbar query is not reloaded and it still shows "Profile". But if I manully refresh the page it shows "Sign in". Seems to me like the query cache is not invalidated after every action.
Brendonovich
Brendonovich3w ago
Ah the query refetch is probably being done as a single flight mutation, if your auth check reads headers or cookies then it'll be reading from the incoming request
sh03
sh03OP3w ago
Ah yes that would explain it Shit
Brendonovich
Brendonovich3w ago
Try setting singleFlight={false} on the Router and if it works then there's your problem
sh03
sh03OP3w ago
Actually turns out that with a redirect after the action the problem is solved. But I can reproduce it also the other way around (not logged in -> logged in, the nav bar is not updated) but that happens via API routes and not actions (as it's via OAuth) And singleFlight there doesn't help. I'm assuming because via API routes the cache is not invalidated automatically. Any way to invalidate from an API route? 😅 @Brendonovich
Brendonovich
Brendonovich3w ago
You can wrap the api route fetch in an action
sh03
sh03OP3w ago
As in:
export const GET = action(async (event: APIEvent) => {
// ...
});
export const GET = action(async (event: APIEvent) => {
// ...
});
?
Brendonovich
Brendonovich3w ago
Nah just the fetch call you do to it That’s basically what server function compile to anyway
sh03
sh03OP3w ago
I don't do the fetch call. Google does; as a callback. It's the oauth flow. Redirect to google -> Login on google -> Callback to the API route Maybe I can actually convert this to not be an API call Yeah, that should do it. Thanks @Brendonovich 🙏 It's unclear what I'd do without you guys. Probably cry in a corner.
Brendonovich
Brendonovich3w ago
Does this happen in a separate tab? If it's the same tab i dont see why a cache invalidation would be necessary
sh03
sh03OP3w ago
Same tab. I'm assuming that since no action is called in the flow then the cache is not invalidated.
Brendonovich
Brendonovich3w ago
Doesnt that mean the site does a complete reload? I’d think the auth state should just be correct when it redirects back to your site
sh03
sh03OP3w ago
It does, but isn't the cache alive for 5 minutes?
Brendonovich
Brendonovich3w ago
not unless you add cache headers, cache/query is per-request
sh03
sh03OP3w ago
Isn't there also a local cache? Client side I mean
Brendonovich
Brendonovich3w ago
Only in-memory, if you leave + enter your site all the caches will be empty
sh03
sh03OP3w ago
Then it is a mystery. For the time being I'm just converting to using action and query instead. Let's see how that goes.
Want results from more Discord servers?
Add your server