S
SolidJS•2y ago
im_ninooo

Await for signal state?

My website checks the login state upon initial load and a Resource on a page is failing to load because it requires login but it runs before the login check can finish. How can I wait for the logged-in (signal) state to change before proceeding with the request? I've looked at the from documentation but it's very confusing.
29 Replies
Tommypop
Tommypop•2y ago
You can add the login signal as the resource source:
const [isLoggedIn, setIsLoggedIn] = createSignal(false);
const [data] = createResource(isLoggedIn, async (val) => {
// This will run when the isLoggedIn signal is truthy, and when it changes.
})
const [isLoggedIn, setIsLoggedIn] = createSignal(false);
const [data] = createResource(isLoggedIn, async (val) => {
// This will run when the isLoggedIn signal is truthy, and when it changes.
})
im_ninooo
im_ninoooOP•2y ago
ooohhhh, I did not know that. if so that's perfect, thank you! it works!
Tommypop
Tommypop•2y ago
Awesome
im_ninooo
im_ninoooOP•2y ago
thank you very much 😄
Tommypop
Tommypop•2y ago
The createResource API is not particularly well documented You're welcome :)
im_ninooo
im_ninoooOP•2y ago
it does explain this behavior, but it's been a while since I've read createResource()'s docs and I probably skipped the large chunk of text where it is explained 😅
im_ninooo
im_ninoooOP•2y ago
I was looking at the older(?) website but it says the exact same thing https://www.solidjs.com/docs/latest#createresource anyway, I'll close this now 😄 thanks again
Tommypop
Tommypop•2y ago
dw
im_ninooo
im_ninoooOP•2y ago
hello, I'm reopening this because I can't seem to be able to tell when the resource hasn't yet started fetching as it's initial state is ready. is this expected behavior?
im_ninooo
im_ninoooOP•2y ago
I'd expect the initial state to be unresolved or pending. (I'm on version 1.6.5 btw so maybe that already got fixed)
Tommypop
Tommypop•2y ago
I think it might report ready if the source is falsy, as it's value will just be undefined I think You can just use the value of your signal I suppose
im_ninooo
im_ninoooOP•2y ago
yeah, maybe but it would be nice if I could simply use the resource's state in my logic also, in which case would the state be unresolved? it seems like it would be for such cases
im_ninooo
im_ninoooOP•2y ago
im_ninooo
im_ninoooOP•2y ago
unless an undefined value is considered resolved, which to me doesn't make sense (since it is undefined). my issue is that when the state is ready and the resource is undefined, I show a "No data available" fallback, but because that's also the initial resource state, that message is shown before the fetch begins (and then a "loading" message takes over).
im_ninooo
im_ninoooOP•2y ago
here's a gif demonstrating the loading phase.
im_ninooo
im_ninoooOP•2y ago
this is obviously not a big deal but I would like to show the correct information (or nothing at all). I know this should be possible by hooking into the checkingLogin signal, but that will make my code unnecessarily more complex.
Tommypop
Tommypop•2y ago
Yeah you could probably return null instead of undefined from the resource in the case of no data I suppose the resource kinda has "resolved", as it has executed, noticed that the source is falsy, and returned undefined but it's not very intuitive
Tommypop
Tommypop•2y ago
Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
Tommypop
Tommypop•2y ago
Maybe it's because you're on 1.6.5?
im_ninooo
im_ninoooOP•2y ago
I'll update and try again. I did change my loggedIn signal to be optional and defaulted to undefined meaning the session check hasn't run/finished and that worked but again, hooking solely on the resource's state would be cleaner 🙂
im_ninooo
im_ninoooOP•2y ago
my custom ResourceDisplay component is already a huge mess 😅
im_ninooo
im_ninoooOP•2y ago
I really need to rewrite that.
REEEEE
REEEEE•2y ago
Might be cleaner to make use of Suspense and ErrorBoundary
Tommypop
Tommypop•2y ago
Yeah, Suspense is probably a good idea
im_ninooo
im_ninoooOP•2y ago
..I'll have to read on those again 😅 thanks for the suggestions 🙂
REEEEE
REEEEE•2y ago
small example, not sure if it works
<ErrorBoundary fallback={<p> Error: {props.resource.error.message} </p>}>
<Suspense fallback={<p> {props.loadingText ?? 'loading...'} </p>}>
<Show when={props.hasData} fallback={<p> {!loggedIn() ? props.noDataText ?? 'No data'} </p>}>
{props.children}
</Show>
</Suspense>
</ErrorBoundary>
<ErrorBoundary fallback={<p> Error: {props.resource.error.message} </p>}>
<Suspense fallback={<p> {props.loadingText ?? 'loading...'} </p>}>
<Show when={props.hasData} fallback={<p> {!loggedIn() ? props.noDataText ?? 'No data'} </p>}>
{props.children}
</Show>
</Suspense>
</ErrorBoundary>
im_ninooo
im_ninoooOP•2y ago
alright, updating to 1.7.x did fix it 😄
im_ninooo
im_ninoooOP•2y ago
that's what I expected to see based on the truth table in the docs. if it does, that's significantly cleaner! thank you so much 🙂 I'll close this again, thanks again to both Tommy and REEEEE! the ErrorBoundary here doesn't seem to work.. I thought it was because the resource wasn't being called within it (inside the component) but it's still doesn't seem to work I can just use a <Show when={props.state === 'errored'}>, that's fine
Want results from more Discord servers?
Add your server