createResource returning undefined when data is fetched

I'm just learning solid and did something like a hook? maybe? dunno. Anyways, I'm just calling createResource with a fetch on it and returning it's json. But, for any reason, that fn is returning undefined, even when the data is properly fetched("tested" by logging the json). Code:
const useFetch = <T>(p: UseFetchParams) => {
const [url] = createSignal(createUrl(p));

const [data] = createResource<T>(async () => {
return await fetch(url()).then(async (res) => (await res.json()) as T);
});

return { data, didFetch: data() !== undefined };
};
const useFetch = <T>(p: UseFetchParams) => {
const [url] = createSignal(createUrl(p));

const [data] = createResource<T>(async () => {
return await fetch(url()).then(async (res) => (await res.json()) as T);
});

return { data, didFetch: data() !== undefined };
};
75 Replies
Sun「無用」
Sun「無用」OP2y ago
If I do something like console.log(data()) it would be undefined, every time I try to use it.
REEEEE
REEEEE2y ago
Will url have an initial value when the resource is called? I see you're calling createUrl(p) but does it return a url when the useFetch is used? My guess is that the resource isn't rerun
Sun「無用」
Sun「無用」OP2y ago
what?
REEEEE
REEEEE2y ago
If you want the resource to rerun based on the url signal then you need to pass it in as a source as the first parameter of createResource
Sun「無用」
Sun「無用」OP2y ago
I'm not wanting to rerun it yet Just wanting for it to work.
REEEEE
REEEEE2y ago
Okay, try replacing url() with a static url to fetch from
Sun「無用」
Sun「無用」OP2y ago
...
REEEEE
REEEEE2y ago
I'm trying to see where the issue is
Sun「無用」
Sun「無用」OP2y ago
Lightshot
Screenshot
Captured with Lightshot
REEEEE
REEEEE2y ago
What?
Sun「無用」
Sun「無用」OP2y ago
. I didn't understand anything from that
REEEEE
REEEEE2y ago
Okay, here try this.
const useFetch = <T>(p: UseFetchParams) => {
const [url] = createSignal(createUrl(p));

const [data] = createResource<T>(async () => {
return await fetch('https://jsonplaceholder.typicode.com/posts').then(async (res) => (await res.json()) as T);
});

return { data, didFetch: data() !== undefined };
};
const useFetch = <T>(p: UseFetchParams) => {
const [url] = createSignal(createUrl(p));

const [data] = createResource<T>(async () => {
return await fetch('https://jsonplaceholder.typicode.com/posts').then(async (res) => (await res.json()) as T);
});

return { data, didFetch: data() !== undefined };
};
Does this return not undefined
Sun「無用」
Sun「無用」OP2y ago
That'll return undefined since it's the same code
REEEEE
REEEEE2y ago
You tried it?
Sun「無用」
Sun「無用」OP2y ago
It's the same code, it should have the same output. If your question is if the url is valid, yes it is correct.
REEEEE
REEEEE2y ago
Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
REEEEE
REEEEE2y ago
It doesn't have the same output,
Sun「無用」
Sun「無用」OP2y ago
it should have, though.
REEEEE
REEEEE2y ago
Why?
Sun「無用」
Sun「無用」OP2y ago
. and the url is valid.
REEEEE
REEEEE2y ago
The issue is the url that the resource is trying to access. Meaning, url doesn't have a valid value. If you console.log url() inside the resource before the return what do you get?
Sun「無用」
Sun「無用」OP2y ago
A valid url. Like I said, the url is valid.
REEEEE
REEEEE2y ago
the url itself that you want to fetch from might be valid. I'm saying that the url signal doesn't have a valid value yet Yes, I understand
Sun「無用」
Sun「無用」OP2y ago
yes, it does. It literally fetchs. If I do this
createResource(async () => await fetch(url()).then(res => {
console.log(res)
return res.json();
}));
createResource(async () => await fetch(url()).then(res => {
console.log(res)
return res.json();
}));
This would print a valid response But the return of createResource would still be undefined
REEEEE
REEEEE2y ago
okay, so where are you using the data value?
Sun「無用」
Sun「無用」OP2y ago
In a component
REEEEE
REEEEE2y ago
Could you show how you're using it? I can't seem to replicate it, so the issue could be something else Or make a reproduction in the playground
Sun「無用」
Sun「無用」OP2y ago
const {data} = useFetch({url})}}
REEEEE
REEEEE2y ago
Where is the data function being used?
Sun「無用」
Sun「無用」OP2y ago
Im passing to other components why is that relevant?
REEEEE
REEEEE2y ago
Because I can't replicate the issue, so it could be something else. If you think the issue is still createResource, can you make a minimal reproduction of the issue in the playground
REEEEE
REEEEE2y ago
Okay, putting this in the playground I don't get undefined https://playground.solidjs.com/anonymous/8e08f3af-dcea-482d-a1cd-1de21d46fbec
Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
REEEEE
REEEEE2y ago
So, the issue could be something else..
Sun「無用」
Sun「無用」OP2y ago
solid problem them bc it doesnt work locally
REEEEE
REEEEE2y ago
It could be how you're using the data value Could you show how you're using it? You say you're passing it to components, but how are the components using it?
Sun「無用」
Sun「無用」OP2y ago
Im just doing prop spreading. { ...data() }
REEEEE
REEEEE2y ago
okay, what if you do {...data()}
Sun「無用」
Sun「無用」OP2y ago
I just did a typo there, not used to solid
REEEEE
REEEEE2y ago
Ah okay. Hmm and console logging the data in a createEffect like I did in the playground example still prints out undefined? in the parent component that uses the useFetch
Sun「無用」
Sun「無用」OP2y ago
yes, even if I do it outside or ir inside a createEfct
REEEEE
REEEEE2y ago
outside a createEffect it will be undefined
Sun「無用」
Sun「無用」OP2y ago
the data is just always undedined
REEEEE
REEEEE2y ago
Okay, the best way for me to help you find out the issue is if you can make a reproduction in the playground I'm not getting any info to be able to tell what the issue is
Sun「無用」
Sun「無用」OP2y ago
sec, my laptop's keyboard is a bit broken
Sun「無用」
Sun「無用」OP2y ago
Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
Sun「無用」
Sun「無用」OP2y ago
Kinda same, at least
REEEEE
REEEEE2y ago
Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
REEEEE
REEEEE2y ago
replace use of didFetch with joke()
REEEEE
REEEEE2y ago
Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
Sun「無用」
Sun「無用」OP2y ago
? that shouldn't change anything?
REEEEE
REEEEE2y ago
didFetch isn't reactive
Sun「無用」
Sun「無用」OP2y ago
what about it?
REEEEE
REEEEE2y ago
so it will always be false
Sun「無用」
Sun「無用」OP2y ago
But if I do it without the show, it's still undefined.
REEEEE
REEEEE2y ago
Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
Sun「無用」
Sun「無用」OP2y ago
Locally it goes to the fallback forever
REEEEE
REEEEE2y ago
Which fallback? I removed Show in that example
Sun「無用」
Sun「無用」OP2y ago
It just shows nothing* It's undefined. And why does a random fn changes everything?
REEEEE
REEEEE2y ago
Because variables aren't reactive
const [signal, setSignal] = createSignal(1)

const nextValue = signal()

const nextValueFn = () => signal()
const [signal, setSignal] = createSignal(1)

const nextValue = signal()

const nextValueFn = () => signal()
Here nextValue won't update when the signal changes, but nextValueFn will
Sun「無用」
Sun「無用」OP2y ago
But both are calling the signal both of them should be changed
REEEEE
REEEEE2y ago
Yes, but in Solid only functions are tracked and updated It's the reason why using console.log outside a createEffect won't update
const [signal, setSignal] = createSignal(1)

console.log(signal())
const [signal, setSignal] = createSignal(1)

console.log(signal())
This will print 1 and then never print when the signal updates
Sun「無用」
Sun「無用」OP2y ago
and wait, that doesn't work.
REEEEE
REEEEE2y ago
If you want to use didFetch without using a function explicitly, you can do it this way https://playground.solidjs.com/anonymous/5ec53eb0-36be-4358-9af0-d7487f6adcad But you can't destructure the return of useFetch
Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
Sun「無用」
Sun「無用」OP2y ago
https://prnt.sc/nInWrBQEVKhl Locally.
<div class={styles.App}>
<h1>Joke:</h1>
<Show when={didFetch()} fallback={<p>Could not load the joke.</p>}>
<Joke setup={joke()!.setup} punchline={joke()!.punchline} />
</Show>
</div>
<div class={styles.App}>
<h1>Joke:</h1>
<Show when={didFetch()} fallback={<p>Could not load the joke.</p>}>
<Joke setup={joke()!.setup} punchline={joke()!.punchline} />
</Show>
</div>
Lightshot
Screenshot
Captured with Lightshot
REEEEE
REEEEE2y ago
hmmm didFetch is a function?
return { data, didFetch: () => data() !== undefined };
return { data, didFetch: () => data() !== undefined };
Sun「無用」
Sun「無用」OP2y ago
yes, I'm even calling it.
REEEEE
REEEEE2y ago
Hmmm, and the fallback isn't showing?
Sun「無用」
Sun「無用」OP2y ago
no, just a blank page which just means it's undefined.
REEEEE
REEEEE2y ago
Any errors in the console? Because if nothing is showing up then it's something else At least Joke: should be showing
Sun「無用」
Sun「無用」OP2y ago
No, just vite stuff.
REEEEE
REEEEE2y ago
The browser console?
Sun「無用」
Sun「無用」OP2y ago
Both.
REEEEE
REEEEE2y ago
If <h1>Joke:</h1> from here is not showing up, it must be something else
<div class={styles.App}>
<h1>Joke:</h1>
<Show when={didFetch()} fallback={<p>Could not load the joke.</p>}>
<Joke setup={joke()!.setup} punchline={joke()!.punchline} />
</Show>
</div>
<div class={styles.App}>
<h1>Joke:</h1>
<Show when={didFetch()} fallback={<p>Could not load the joke.</p>}>
<Joke setup={joke()!.setup} punchline={joke()!.punchline} />
</Show>
</div>
Carlo Nyte
Carlo Nyte2y ago
Was this ever resolved?

Did you find this page helpful?