mutate on createResource does not update state
Describe the bug
mutate returned from createResource is setValue (line 723 here) and is oblivious to the loading-state of the resource.
This is an issue, when we use custom state handlers reacting on state while mutating signals in resources.
Your Example Website or App
https://stackblitz.com/edit/solidjs-templates-uwtyzi?file=src%2FApp.tsx
Steps to Reproduce the Bug or Issue
const [resource, { mutate }] = createResource(
() => undefined,
async () => {
return 'test'
}
)
mutate('updated')
resource.latest // 'updated'
resource.state // 'unresolved'
const [resource2, { mutate: mutate2 }] = createResource(async () => {
throw new Error('Boom')
})
mutate2('updated')
console.log(resource2.latest) // 'updated'
console.log(resource2.state) // 'errored'
Expected behavior
As a user I expect a way to set the state after mutation, e.g. to ready after I have mutated the data.
Screenshots or Videos
No response
Platform
- OS: [ macOS]
- Browser: [ Chrome]
- Version: [116]
Additional context
No response
Running into a similar issue here. When I use mutate to manually update a resource, the update does not trigger a re-render.
The same thing is when you trigger a resource inside data function when searchParams are being changed.
When you do navigation createEffect(() => console.log(comments.state)); is always ready
Oh, interesting thing
when I do createComputed(() => console.log(comments.state)); I see
refresing
ready
I suppose this is because of transition happening in the router. However I need to reflect this state in the UI, but UI works like an effect....
How can I reflect state of resource in the UI in transition?
I have a fix for this. The one that always should have been. I do wonder if people were using this in unexpected ways though. The solution is have the mutate call actually call load complete. But it means the setter is no longer transparently sent back. For normal operation this is fine, but I wonder if people might have tried to leverage this with custom signal stores.
EDIT: On further thought this is a breaking change in terms of expected behavior. Mutate right now doesn't cancel inflight fetches either. It's a sort of Signal write vs In flight battle. I could see an argument for having it override and stop in flight but it would be different than it is as designed today.
Running into a similar issue here. When I use mutate to manually update a resource, the update does not trigger a re-render.
This should work fine. The state wasn't being updated but the Signal is. We don't "re-render" in the classic sense so maybe there is a misunderstanding on the read, otherwise I need an example.
How can I reflect state of resource in the UI in transition?
There was another issue about this. Generally you can't because the rest of the app doesn't see it. Your best bet is to use the isRouting or isPending state from the transition to know if it is in flight. I sort of regret adding all these states into the resources because the other mechanisms manage it.
Thank you for the answer! Will come up with some ideas about potential workarounds. I did use isRouting before, however I faced a "bug" when you navigate to another page, the styles for "loading" state are applied, however here's completely different semantics, because we need to apply them only when the resource is being refreshed. That's why I decided to go with resource state, but unfortunately it doesn't work as I'd expect.
Reproduction example: https://playground.solidjs.com/anonymous/181aed31-efe8-492b-a8b7-e15f43e9a123