suspense + store

if I have a form tied to a store that gets populated async, how do i use this with <suspense so i don't need loading state management
22 Replies
thetarnav
thetarnav2y ago
the deep signal was added to solid-primitives too: https://primitives.solidjs.community/package/resource#createdeepsignal
Solid Primitives
A library of high-quality primitives that extend SolidJS reactivity
Braveheart
BraveheartOP2y ago
any simple example for this? is this correct?
Braveheart
BraveheartOP2y ago
import { createResource, createStore } from "solid-js";

const caseStore = createStore({});

function MyComponent() {
const [caseId, setCaseId] = createSignal(0);
const [caseResource] = createResource(() =>
fetch(`/api/cases/${caseId()}`).then((res) => res.json())
);

const caseData = caseStore[caseId()] || caseResource();

// Use caseData in your component logic
// ...

return (
<div>
<h1>Case {caseId()}</h1>
<button onClick={() => setCaseId(caseId() + 1)}>Next Case</button>
{/* ... */}
</div>
);
}
import { createResource, createStore } from "solid-js";

const caseStore = createStore({});

function MyComponent() {
const [caseId, setCaseId] = createSignal(0);
const [caseResource] = createResource(() =>
fetch(`/api/cases/${caseId()}`).then((res) => res.json())
);

const caseData = caseStore[caseId()] || caseResource();

// Use caseData in your component logic
// ...

return (
<div>
<h1>Case {caseId()}</h1>
<button onClick={() => setCaseId(caseId() + 1)}>Next Case</button>
{/* ... */}
</div>
);
}
mdynnl
mdynnl2y ago
👆
Braveheart
BraveheartOP2y ago
i just want the simplest example possible, can't find exact what I want in the tutorial
Braveheart
BraveheartOP2y ago
this works, but its just a signal that returns I think, so i just need to update companyDetailsResource with the deep properties in the form before I used resource and <suspend> i had loading management and onChange={(e) => setCompanyDetailsStore('country', e.currentTarget.value)}>
mdynnl
mdynnl2y ago
this release introduced storage option in createResource, also has an example integrating createStore => createDeepSignal + storage which makes res() => store, { mutate } => setStore (with reconcile) and thetarnav added that createDeepSignal (i guess) to solid primitives so you can just grab it from there, which also has a simple example integrating the two but yeah, it could be improved with more usage example i guess
Braveheart
BraveheartOP2y ago
thx, so the primative is sugar? createDeepSignal is from solid.js?
mdynnl
mdynnl2y ago
a helper for your convenience crafted by a magician 🪄 nah, the release link includes the implementation .
Braveheart
BraveheartOP2y ago
my devs gonna be confused no end lol
mdynnl
mdynnl2y ago
which is probably the same as the solid primitive one
Braveheart
BraveheartOP2y ago
cool
Braveheart
BraveheartOP2y ago
How do I update a store in this way? is there a setter?
thetarnav
thetarnav2y ago
[data, { mutate }] mutate is pretty much a signal setter but since it's a "deep signal" it will reconcile on every set there is probably a way to expose the path syntax and produce too but the typescript part is tricky haven't looked into that yet
Braveheart
BraveheartOP2y ago
Braveheart
BraveheartOP2y ago
getting this error
//create resource for the data
const [companyDetailsResource, { mutate }] = createResource(
() => {
return getCompanyCaseDetails(caseId);
},
{
storage: createDeepSignal,
}
);
//create resource for the data
const [companyDetailsResource, { mutate }] = createResource(
() => {
return getCompanyCaseDetails(caseId);
},
{
storage: createDeepSignal,
}
);
will I guess I can set the data in a new clone of the resource, since the gql data response should not change
Braveheart
BraveheartOP2y ago
why can't we type the resource
thetarnav
thetarnav2y ago
as I said it's more like signal setter then store setter if you see the source code for the deep signal youll see what's getting returned as a setter
Braveheart
BraveheartOP2y ago
ok ah the type comes from the fetcher what ill do is clone the resource result and tie that to the form and mutate that hmmm, donno then i lose the suspense feature i guess i will make the intital value for the form inputs equal to there resource and the cloned store used in the mutations nah that aint gonna work, cause the value= value={companyDetailsResource()?.companyDetails.registeredAddress.country} im back to where i started lol two simple stores without <suspense just seems easier to manage for me and my devs at least i know how to use a read only resource tho, thx i dont see function createDeepSignal<T>(value: T): Signal<T> { anywhere in source tho in either repo
thetarnav
thetarnav2y ago
you could play with this too if you don't need to reconcile, but just use the resource as an initial state 🤷‍♂️
const [resource] = createResource(() => {...})

const store = createMemo(() => createStore(resource() ?? {}))

<Suspense>
<Show when={resource()}>
<App state={store()[0]} setState={store()[1]} />
</Show>
</Suspense>
const [resource] = createResource(() => {...})

const store = createMemo(() => createStore(resource() ?? {}))

<Suspense>
<Show when={resource()}>
<App state={store()[0]} setState={store()[1]} />
</Show>
</Suspense>
it's just createStore + reconcile https://github.com/solidjs-community/solid-primitives/blob/main/packages/resource/src/index.ts#L256
Braveheart
BraveheartOP2y ago
i dont want to scrare off the react devs too many layers of complexity here vs two stores ill wrap the whole form in a <show with initial store> and just have the 2nd store as the original comparison I've decided to do this:
onMount(async () => {
originalData = await getCompanyCaseDetails(caseId);
setCompanyDetailsStore(originalData);
debugger
});

//clone originalData into a store which will be used for editing and comparing changes to the data in the resource and saving
const [companyDetailsStore, setCompanyDetailsStore] = createStore(undefined);
return (
<>
<Show when={companyDetailsStore !== undefined}>
onMount(async () => {
originalData = await getCompanyCaseDetails(caseId);
setCompanyDetailsStore(originalData);
debugger
});

//clone originalData into a store which will be used for editing and comparing changes to the data in the resource and saving
const [companyDetailsStore, setCompanyDetailsStore] = createStore(undefined);
return (
<>
<Show when={companyDetailsStore !== undefined}>
but calling companyDetailsStore throws error caught ReferenceError: companyDetailsStore is not defined what should that <show statement be like?
Want results from more Discord servers?
Add your server