S
SolidJS3y ago
Sun

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
SunOP3y ago
If I do something like console.log(data()) it would be undefined, every time I try to use it.
REEEEE
REEEEE3y 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
SunOP3y ago
what?
REEEEE
REEEEE3y 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
SunOP3y ago
I'm not wanting to rerun it yet Just wanting for it to work.
REEEEE
REEEEE3y ago
Okay, try replacing url() with a static url to fetch from
Sun
SunOP3y ago
...
REEEEE
REEEEE3y ago
I'm trying to see where the issue is
Sun
SunOP3y ago
Lightshot
Screenshot
Captured with Lightshot
REEEEE
REEEEE3y ago
What?
Sun
SunOP3y ago
. I didn't understand anything from that
REEEEE
REEEEE3y 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
SunOP3y ago
That'll return undefined since it's the same code
REEEEE
REEEEE3y ago
You tried it?
Sun
SunOP3y 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
REEEEE3y ago
Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
REEEEE
REEEEE3y ago
It doesn't have the same output,
Sun
SunOP3y ago
it should have, though.
REEEEE
REEEEE3y ago
Why?
Sun
SunOP3y ago
. and the url is valid.
REEEEE
REEEEE3y 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
SunOP3y ago
A valid url. Like I said, the url is valid.
REEEEE
REEEEE3y 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
SunOP3y 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
REEEEE3y ago
okay, so where are you using the data value?
Sun
SunOP3y ago
In a component
REEEEE
REEEEE3y 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
SunOP3y ago
const {data} = useFetch({url})}}
REEEEE
REEEEE3y ago
Where is the data function being used?
Sun
SunOP3y ago
Im passing to other components why is that relevant?
REEEEE
REEEEE3y 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
Sun
SunOP3y ago
REEEEE
REEEEE3y 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
REEEEE3y ago
So, the issue could be something else..
Sun
SunOP3y ago
solid problem them bc it doesnt work locally
REEEEE
REEEEE3y 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
SunOP3y ago
Im just doing prop spreading. { ...data() }
REEEEE
REEEEE3y ago
okay, what if you do {...data()}
Sun
SunOP3y ago
I just did a typo there, not used to solid
REEEEE
REEEEE3y 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
SunOP3y ago
yes, even if I do it outside or ir inside a createEfct
REEEEE
REEEEE3y ago
outside a createEffect it will be undefined
Sun
SunOP3y ago
the data is just always undedined
REEEEE
REEEEE3y 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
SunOP3y ago
sec, my laptop's keyboard is a bit broken
Sun
SunOP3y ago
Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
Sun
SunOP3y ago
Kinda same, at least
REEEEE
REEEEE3y ago
Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
REEEEE
REEEEE3y ago
replace use of didFetch with joke()
REEEEE
REEEEE3y ago
Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
Sun
SunOP3y ago
? that shouldn't change anything?
REEEEE
REEEEE3y ago
didFetch isn't reactive
Sun
SunOP3y ago
what about it?
REEEEE
REEEEE3y ago
so it will always be false
Sun
SunOP3y ago
But if I do it without the show, it's still undefined.
REEEEE
REEEEE3y ago
Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
Sun
SunOP3y ago
Locally it goes to the fallback forever
REEEEE
REEEEE3y ago
Which fallback? I removed Show in that example
Sun
SunOP3y ago
It just shows nothing* It's undefined. And why does a random fn changes everything?
REEEEE
REEEEE3y 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
SunOP3y ago
But both are calling the signal both of them should be changed
REEEEE
REEEEE3y 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
SunOP3y ago
and wait, that doesn't work.
REEEEE
REEEEE3y 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
SunOP3y 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
REEEEE3y ago
hmmm didFetch is a function?
return { data, didFetch: () => data() !== undefined };
return { data, didFetch: () => data() !== undefined };
Sun
SunOP3y ago
yes, I'm even calling it.
REEEEE
REEEEE3y ago
Hmmm, and the fallback isn't showing?
Sun
SunOP3y ago
no, just a blank page which just means it's undefined.
REEEEE
REEEEE3y ago
Any errors in the console? Because if nothing is showing up then it's something else At least Joke: should be showing
Sun
SunOP3y ago
No, just vite stuff.
REEEEE
REEEEE3y ago
The browser console?
Sun
SunOP3y ago
Both.
REEEEE
REEEEE3y 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>
Lo | Building Dromo
Was this ever resolved?

Did you find this page helpful?