S
SolidJS15mo ago
Nin

How to mutate a createResource storage

Hi all, I'd like to get some help with mutating a store that is set as a createResource storage.
function createDeepSignal<T>(value: T): Signal<T> {
const [store, setStore] = createStore({
value
});
return [
() => store.value,
(v: T) => {
const unwrapped = unwrap(store.value);
typeof v === "function" && (v = v(unwrapped));
setStore("value", reconcile(v));
return store.value;
}
] as Signal<T>;
}

const [resource, {mutate, refetch}] = createResource(fetcher, {
storage: createDeepSignal
});
function createDeepSignal<T>(value: T): Signal<T> {
const [store, setStore] = createStore({
value
});
return [
() => store.value,
(v: T) => {
const unwrapped = unwrap(store.value);
typeof v === "function" && (v = v(unwrapped));
setStore("value", reconcile(v));
return store.value;
}
] as Signal<T>;
}

const [resource, {mutate, refetch}] = createResource(fetcher, {
storage: createDeepSignal
});
Given the above snippet, I can access my store regularly by running resource() this returns the contents of my store, but how can I mutate it? Mutate only accepts one argument and usually setStore would receive multiple.
11 Replies
foolswisdom
foolswisdom15mo ago
I think you need to use mutate function as normal, and rely on reconcile to ensure fine grained updates So no, you will not be able to use the store setter API Let us know if that works
Nin
NinOP15mo ago
So I just call update with the new array in this case?
foolswisdom
foolswisdom15mo ago
Yes
Nin
NinOP15mo ago
Interesting, OK, going to give that a shot! Thanks a lot @foolswisdom
foolswisdom
foolswisdom15mo ago
(this is, in general, the point of the reconcile function - it does data diffing for situations when you don't know ahead of time what the change will look like / where the change will be. Like receiving updated data from an API)
Nin
NinOP15mo ago
Alright that makes sense then yeah. I thought it would return the setter from the store to be the mutate function and was trying to use the setter API. This makes it easy though. I'll give it a shot and report back here once I've done so. Right now a pizza is waiting for me so have to run
bradleyhogle
bradleyhogle15mo ago
@arvalaan @foolswisdom Would one of you be willing to post a snippet of a working version of that? I understand if not, but I'm working with a similar issue and trying to grok combining stores with createResource, as it seems to be absent from the documentation as a possibility.
foolswisdom
foolswisdom15mo ago
Example of what? The snippet in the original post pretty much sums up how you use it
bradleyhogle
bradleyhogle15mo ago
Sorry, still getting the hang of createResource. I made a basic playground utilizing the snippet. My (incorrect) attempt at updating as you suggest, using mutate, is in the click handler. Currently it doesn't throw any errors, but also doesn't update. https://playground.solidjs.com/anonymous/06c4a426-68ef-4216-8137-b2415fc4722e
Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
foolswisdom
foolswisdom15mo ago
Try
const click = () =>
mutate({
...unwrap(resource()),
films: ["Star Wars Holiday Special", "Ewok Adventures"],
});
const click = () =>
mutate({
...unwrap(resource()),
films: ["Star Wars Holiday Special", "Ewok Adventures"],
});
reconcile can get confused if you reuse the old object iirc I don't remember the details about that, sorry Normally you don't want to blow out the old version, but reconcile operates by diffing two different objects (and then fine-grained mutating the store to match the new version)
bradleyhogle
bradleyhogle15mo ago
Excellent, thank you so much. Didn't think to just destructure that way, clever.
Want results from more Discord servers?
Add your server