reactive initialValue on createResource

is it possible to make initialValue react based on a signal? I have this:
const [namespaces] = createResource(contexts, fetchNamespaces, {
initialValue: getCachedNamespaces(contexts()),
});
const [namespaces] = createResource(contexts, fetchNamespaces, {
initialValue: getCachedNamespaces(contexts()),
});
Whenever the list of contexts change, it'll refetch the namespaces for that contexts. But the initialValue does not as it's evaluated once on render. I want to build sort of a cache, so whenever the context changes, the list of namespaces will be whatever is cached (localstorage) and then it'll refresh shortly after.
6 Replies
goenning
goenning2y ago
this works, but I suspect it might have some race conditions here in case the mutate happens after fetch:
const [namespaces, { mutate }] = createResource(contexts, fetchNamespaces);

createEffect(() => {
const ctxs = contexts();
mutate(getCachedNamespaces(ctxs));
});
const [namespaces, { mutate }] = createResource(contexts, fetchNamespaces);

createEffect(() => {
const ctxs = contexts();
mutate(getCachedNamespaces(ctxs));
});
Alex Lohr
Alex Lohr2y ago
You can simply not run the effect if namespaces() is not undefined. Don't forget to untrack it inside the effect: if (untrack(namespaces) !== undefined) { ... }
Unknown User
Unknown User2y ago
Message Not Public
Sign In & Join Server To View
Alex Lohr
Alex Lohr2y ago
Ah, yes. Well, then you'll need an extra variable that is set inside the fetcher. Or you return the last value of the context and compare with that.
goenning
goenning2y ago
So basically there’s no way to do it without the effect? Just with the createResource?
Alex Lohr
Alex Lohr2y ago
Well, you could also derive the resource in a memo instead and use that:
const namespace = createMemo(() => !serverNamespaces.error && serverNamespaces() || getCachedNamespaces(contexts()))
const namespace = createMemo(() => !serverNamespaces.error && serverNamespaces() || getCachedNamespaces(contexts()))
then you don't have to mutate the resource and will always get the newest initialValue (that only gets updated when either serverNamespaces or contexts() changes).